国际奥委会类库。 凡引导(IoC in class library. Where to boot

2019-06-23 16:51发布

我使用的是一个类库,可以由其他组件重用。 在这个类库我使用依赖注入的统一。 对于这个类库我创建一个测试项目。 呼叫者也获得一个测试项目。 有一件事我不确定是绑定的位置。 我应该类库中包含这还是我应该这样做从调用应用程序?

Answer 1:

这是一个有趣的问题。 你怎么能依赖注入没有切入点,可重用的组件。 我真的想看到其他人的答案。

依赖注入是入口点组件的责任。 然而,如果你有很多类和组件,每个需要DI,那么很可能他们是左关闭一些类/组件和任务变得繁重。

解决方案一

使用约定优于配置。 你坚持类的规则Foo实现IFoo等很多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)
        {
            ....
        }
    }
}

然后在入口点,我有一个共同的代码看起来通过具有集属性,然后寻找实现该类型的所有加载的程序集(包括MEFed的) IIocInstaller ,然后调用安装在他们身上。



Answer 2:

我知道,答案已经被选择,但是我认为统一的一部分被忽视。 由于这是一个特定的团结问题,我想我指出,实现IUnityContainerExtensionConfigurator的UnityContainerExtension基类。 这是有API库扩展,可以很容易的进入点应用谁拥有集装箱有一个简单的方法,以确保您的图书馆获取与集装箱正确注册,并允许什么获取注册API所有者控制和怎么样。

这是为了这个目的所使用的微软企业库。

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

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

然后入口点的应用程序做到这一点:

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

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

    // ...
}

现在,他们已经登记注册的企业库和日志记录库的API。 它是用这种方法这就是图书馆的任何开发者都应该作为一个目标入口点的应用程序非常简单。



Answer 3:

从调用应用程序这样做将更多的负担,调用应用程序。 离开省略初始化和陷入困境的机会。

我会做的类库,例如在静态构造函数。



Answer 4:

OK创建一个名为Project.Ioc库。 这里安装统一。 参考其他层国际奥委会库。 和IOC图书馆表示层。 创建一个名为UnityHelper类。

/// <summary>
/// Bind the given interface in request scope
/// </summary>
public static class IocExtensions
{
    public static void BindInRequestScope<T1, T2>(this IUnityContainer container) where T2 : T1
    {
        container.RegisterType<T1, T2>(new HierarchicalLifetimeManager());
    }

    public static void BindInSingletonScope<T1, T2>(this IUnityContainer container) where T2 : T1
    {
        container.RegisterType<T1, T2>(new ContainerControlledLifetimeManager());
    }
}

/// <summary>
/// The injection for Unity
/// </summary>
public static class UnityHelper
{

    public static IUnityContainer Start()
    {
        var container = BuildUnityContainer();

        DependencyResolver.SetResolver(new Unity.Mvc4.UnityDependencyResolver(container));

        return container;
    }

    /// <summary>
    /// Inject
    /// </summary>
    /// <returns></returns>
    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<IMVCForumContext, MVCForumContext>();
        container.BindInRequestScope<IUnitOfWorkManager, UnitOfWorkManager>();

        //Bind the various domain model services and repositories that e.g. our controllers require         
        container.BindInRequestScope<ITopicService, TopicService>();

        container.BindInRequestScope<ITopicTagRepository, TopicTagRepository>();

        //container.BindInRequestScope<ISessionHelper, SessionHelper>();

        return container;
    }
}

退房MvcForum项目。 有MvcForm.Ioc类库。 这家图书馆其它层的引用。 有只有一个名为UnityHelper类。

https://github.com/leen3o/mvcforum

我希望这是你正在寻找笏。



文章来源: IoC in class library. Where to bootstrap