gpt4 book ai didi

c# - Autofac 在深层解析

转载 作者:太空宇宙 更新时间:2023-11-03 12:52:58 26 4
gpt4 key购买 nike

我很难将 autofac 集成到我的应用程序中..

当与另一个应用程序的连接由合适的“协议(protocol)”对象维护时,我的应用程序与其他应用程序集成

// This class is inherited by a few other classes
public abstract class Protocol

我有一个由它自己的线程运行并处理连接请求的层。对于每种请求,都会创建不同类型的协议(protocol)(不同的协议(protocol)对象)

// For example lets say every protocol (Inhertiance of Protocol abstract object) 
// takes in ctor these 3 services + runtime configuration object:
public Protocol1(IFramingAgent, IFramingAlgorithm, IFramingParser, configObject configuration)

我的协议(protocol)对象被键控注册为协议(protocol)。还,每个服务都使用 key 注册,因为每个协议(protocol)使用从同一接口(interface)继承的不同类型。当然,所有这些都注册为 PerDependency(虽然我不太明白这个 lifeCycle 与 PerScope 之间的区别,非常感谢解释)

这是我糟糕的类(class):

public class ProtocolsLayer : Layer
{
private IFrameworkDependencyResolver _resolver;
private IConfigurationService _configService;

public ProtocolsLayer(IFrameworkDependencyResolver resolver, IConfigurationService configurationService)
{
_resolver = resolver;
_configService = configurationService;
}

void HandleConnection1()
{
// What I have at the moment (terrible):

// Resolve the fitting services (All keyed - key is received by the type, Resolve and ResolveWithParameters used here are my wrappers)
var agent = _resolver.Resolve<IFramingAgent>(typeof(Protocol1FramingAgent));

var algo = _resolver.Resolve<IFramingAlgorithm>(typeof(Protocol1FramingAlgorith));

var parser = _resolver.Resolve<IFramingParser>(typeof(Protocol1FramingParser));

// A parameter I get and pass to each protocol at runtime
var protocolConfig = _configService.GetConfig<Protocol1Configuration>();

// Finally resolve the protocol with it's parameters:

protocol = _resolver.ResolveWithParameters<IProtocol>(typeof(Protocol1), new List<object>{
agent, resolver, parser, protocolConfig
});

//...

// Theres gotta be a better way!!
}

void HandleConntection2()
{
// Same as in protocol1
}

void HandleConnection3()
{
// Same as in protocol1
}
}

请记住,我不想引用 autofac,这意味着我不能使用我听说过的 IIndex<>。

谢谢!

最佳答案

你应该让依赖注入(inject)框架管理实例化。

您使用 ResolveWithParameter这些参数已由依赖注入(inject)框架解析的方法。这不是必需的,您可以让框架为您找到依赖项:

如果Protocol1需要一个命名参数,您可以在注册过程中指定它。

builder.Register(c => c.Resolve<IConfigurationService>()
.GetConfig<Protocol1Configuration>())
.As<Protocol1Configuration>();

builder.RegisterType<Protocol1>()
.Named<IProtocol1>(nameof(Protocol1))
.WithParameter((pi, c) => pi.ParameterType == typeof(IFramingAgent),
(pi, c) => c.ResolveNamed<IFramingAgent>(nameof(Protocol1))
.WithParameter((pi, c) => pi.ParameterType == typeof(IFramingAlgorithm),
(pi, c) => c.ResolveNamed<IFramingAlgorithm>(nameof(Protocol1));
builder.RegisterType<FramingAgentProtocol1>()
.Named<IFramingAgent>(nameof(Protocol1));
builder.RegisterType<FramingAlgorithmProtocol1>()
.Named<IFramingAlgorithm>(nameof(Protocol1));

然后ProtocolsLayer只需要依赖 IIndex<String, Func<IProtocol>> (或 Func<Owned<Protocol1>>)

public class ProtocolsLayer 
{
public ProtocolsLayer(IIndex<String, Func<IProtocol>> index)
{
this._index = index;
}

private readonly IIndex<String, Func<IProtocol>> _index;

public void HandleConnection1()
{
IProtocol protocol = this._index[nameof(Protocol1)]();
}
}

如果不想引入对IIndex<,>的依赖对于您的整个应用程序,您可以引入 IProtocolFactory将在您的运行时中定义并仅为注册项目创建实现。

在您的运行时项目中:

public interface IProtocolFactory
{
IProtocol Create(String protocolName)
}

在您的注册项目中:

public class ProtocolFactory : IProtocolFactory
{

public ProtocolFactory(IIndex<String, IProtocol> index)
{
this._index = index;
}

private readonly IIndex<String, IProtocol> _index;

public IProtocol Create(String protocolName)
{
return this._index[typeof(TProtocol).Name];
}
}

那你ProtocolsLayer类将如下所示:

public class ProtocolsLayer 
{
public ProtocolsLayer(IProtocolFactory protocolFactory)
{
this._protocolFactory = protocolFactory;
}

private readonly IProtocolFactory _protocolFactory;

public void HandleConnection1()
{
IProtocol protocol = this._protocolFactory.Create("Protocol1");
}
}

您还可以注册 Func<String, IProtocol>这将命名为 resolve IProtocol

ProtocolsLayer看起来像这样:

public class ProtocolsLayer 
{
public ProtocolsLayer(Func<String, IProtocol> protocolFactory)
{
this._protocolFactory = protocolFactory;
}

private readonly Func<String, IProtocol> _protocolFactory;

public void HandleConnection1()
{
IProtocol protocol = this._protocolFactory("Protocol1");
}
}

和这样的注册:

builder.Register(c => (String namedProtocol) => c.ResolveNamed<IProtocol>(namedProtocol)
.As<Func<String, IProtocol>>();

但我不会推荐这个解决方案,因为 Func<String, IProtocol> protocolFactory 的意图依赖关系不明确。有一个 IProtocolFactory接口(interface)使依赖目标易于理解。

关于c# - Autofac 在深层解析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34908017/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com