IoC在类库中.在哪里引导

Pat*_*ick 30 c# dependency-injection inversion-of-control unity-container

我正在使用可以被其他组件重用的类库.在这个类库中,我使用unity来进行依赖注入.对于这个类库,我创建了一个测试项目.调用者也获得了一个测试项目.我不确定的一件事是绑定的位置.我应该在类库中加入它还是应该从调用应用程序中执行此操作?

Rod*_*ley 27

我知道已经选择了答案,但我认为Unity的一部分被忽略了.由于这是一个特定的Unity问题,我想我指出了实现IUnityContainerExtensionConfigurator的UnityContainerExtension基类.这是为了扩展API库,使拥有Container的入口点应用程序可以轻松地确保您的库正确地注册到Container,并允许API所有者控制注册的内容和怎么样.

为此,Microsoft Enterprise Libraries使用它.

我将使用Logging库作为一个简单的:

public class LoggingUnityExtension : UnityContainerExtension
{
    protected override void Initialize()
    {
        Container.RegisterType<ILogger, Logger>(new ContainerControlledLifetimeManager());
    }
}
Run Code Online (Sandbox Code Playgroud)

然后入口点应用程序执行此操作:

public class Bootstrapper : UnityBootstrapper
{
    protected override void ConfigureContainer()
    {
        base.ConfigureContainer();

        Container.AddNewExtension<EnterpriseLibraryCoreExtension>();
        Container.AddNewExtension<LoggingUnityExtension>();
        // ... 
    }

    // ...
}
Run Code Online (Sandbox Code Playgroud)

现在,他们已经注册了Enterprise Library和Logging库的API.使用此方法的入口点应用程序非常简单,这是任何库开发人员应该具有的目标.


Ali*_*tad 8

这是一个有趣的问题.如何依赖注入没有入口点的可重用组件.我真的很想看到其他人的回答.

依赖注入是入口点组装的责任.然而,如果你有很多需要DI的类和程序集,那么对于某些类/程序集来说它们可能是空闲的,而且任务变得繁重.

解决方案一

使用约定优于配置.你坚持使用类Foo实现IFoo等规则.很多DI框架都有使用约定来设置它的方法.

解决方案二

以上解决方案并不能解决所有问题,因为有时您需要参数化注射设置.这是我解决问题的方法(特别是对于那些由MEF加载的程序集,这是为了AutoFac):

创建了一个IIocInstaller容器(或构建器通过)的接口

public interface IIocInstaller
{
    void Setup(ContainerBuilder builder);
}
Run Code Online (Sandbox Code Playgroud)

创建一个程序集属性,标记需要DI的程序集:

[AttributeUsage(AttributeTargets.Assembly)]
public class ExportAssemblyAttribute : Attribute
{
}
Run Code Online (Sandbox Code Playgroud)

在每个程序集中,我创建了一个设置DI的类:

[assembly: ExportAssembly]
namespace This.That
{

    [Export(typeof(IIocInstaller))]
    public class IocInstaller : IIocInstaller
    {
        public void Setup(ContainerBuilder builder)
        {
            ....
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在入口点,我有一个公共代码,它查看具有assembly属性的所有已加载程序集(包括MEFed程序集),然后查找实现它的类型IIocInstaller,然后在它们上调用Setup.