Autofac在深层解析

时间:2016-01-20 18:45:49

标签: c# dependency-injection autofac resolve

我很难将autofac集成到我的applcation中。

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

->with()

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

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

我的协议对象被键控注册为协议。也, 每个服务都使用密钥注册,因为每个协议使用从同一接口继承的不同类型。当然,所有这些都被注册为PerDependency(虽然我真的不明白这个lifeCycle与PerScope之间的区别,真的很感激解释)

这是我可怕的课程:

// 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)

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

谢谢!

1 个答案:

答案 0 :(得分:1)

您应该让依赖注入框架管理实例化。

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

如果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"); 
    }
}

您还可以注册一个名为resolve Func<String, IProtocol>

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接口使得依赖目标易于理解。