IoC在类库中。 在哪里引导

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

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

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

解决方案一

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

解决方案二

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

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

 public interface IIocInstaller { void Setup(ContainerBuilder builder); } 

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

 [AttributeUsage(AttributeTargets.Assembly)] public class ExportAssemblyAttribute : Attribute { } 

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

 [assembly: ExportAssembly] namespace This.That { [Export(typeof(IIocInstaller))] public class IocInstaller : IIocInstaller { public void Setup(ContainerBuilder builder) { .... } } } 

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

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

为此,Microsoft Enterprise Libraries使用它。

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

 public class LoggingUnityExtension : UnityContainerExtension { protected override void Initialize() { Container.RegisterType(new ContainerControlledLifetimeManager()); } } 

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

 public class Bootstrapper : UnityBootstrapper { protected override void ConfigureContainer() { base.ConfigureContainer(); Container.AddNewExtension(); Container.AddNewExtension(); // ... } // ... } 

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

从调用应用程序执行此操作会给调用应用程序带来更多负担。 没有机会省略初始化并陷入困境。

我会在类库中执行它,例如在静态构造函数中。

确定创建名为Project.Ioc的库。 在这里安装Unity。 将其他图层引用到Ioc库。 和Ioc Library到表示层。 创建一个名为UnityHelper的类。

 ///  /// Bind the given interface in request scope ///  public static class IocExtensions { public static void BindInRequestScope(this IUnityContainer container) where T2 : T1 { container.RegisterType(new HierarchicalLifetimeManager()); } public static void BindInSingletonScope(this IUnityContainer container) where T2 : T1 { container.RegisterType(new ContainerControlledLifetimeManager()); } } ///  /// The injection for Unity ///  public static class UnityHelper { public static IUnityContainer Start() { var container = BuildUnityContainer(); DependencyResolver.SetResolver(new Unity.Mvc4.UnityDependencyResolver(container)); return container; } ///  /// Inject ///  ///  private static IUnityContainer BuildUnityContainer() { var container = new UnityContainer(); // register all your components with the container here // it is NOT necessary to register your controllers // Database context, one per request, ensure it is disposed container.BindInRequestScope(); container.BindInRequestScope(); //Bind the various domain model services and repositories that eg our controllers require container.BindInRequestScope(); container.BindInRequestScope(); //container.BindInRequestScope(); return container; } } 

看看MvcForum项目。 有MvcForm.Ioc类库。 该库获取其他Layer引用。 只有一个名为UnityHelper的类。

https://github.com/leen3o/mvcforum

我希望这是你正在寻找的wat。