加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

.net – 如何使用Unity DI加载具有依赖项的程序集,然后注册内部

发布时间:2020-12-14 04:52:42 所属栏目:百科 来源:网络整理
导读:我有一个asp.net mvc 3 Web应用程序,它具有实现系统相关EFcontexts和服务的插件程序集. 例如,我有一个看起来像下面这样的程序集: System1Controller : IController // from System.Web.MvcISystem1Service { IListSystem1Type GetOperation(string somethin
我有一个asp.net mvc 3 Web应用程序,它具有实现系统相关EFcontexts和服务的插件程序集.

例如,我有一个看起来像下面这样的程序集:

System1Controller : IController // from System.Web.Mvc

ISystem1Service {
    IList<System1Type> GetOperation(string something);
}

System1Service : ISystem1Service 
{
    private ISystem1Entities context;
    public System1Service(ISystem1Entities context)
    {
        this.context = context;
    }
}

ISystem1Entities
{
    IDbSet<System1Type> Operations { get; set; }
}

System1Entities : DbContext,ISystem1Entities

使用Unity Bootstrapper并调用Bootstrapper.Initialize()与以下BuildUnityContainer()实现一起使用

private static IUnityContainer BuildUnityContainer()
{
    var theContainer = new UnityContainer();
    var connectionString = ConfigurationManager.ConnectionStrings["WebAppConnectionString"];
    if (connectionString == null)
    {
        throw new ApplicationException("The ConnectionString is not defined.");
    }

    // register all your components with the container here
    // it is NOT necessary to register your controllers
    theContainer.RegisterType<ISystem1Entities,System1Entities>(
        new HierarchicalLifetimeManager(),new InjectionConstructor(connectionString.ConnectionString));

    theContainer.RegisterType<ISystem1Service,System1Service>();

    var factory = new UnityControllerFactory(theContainer);
    ControllerBuilder.Current.SetControllerFactory(factory);

    return theContainer;
}

我想重构引导程序,以便我可以在编译时程序集加载’unknown’,注册其中包含的类型,并允许Web应用程序根据需要引用控制器,服务和上下文.

我已经看过Unity AutoRegistraion项目了,它似乎让我进入了我想要的实现的附近,但我不确定如何实现以下想法:

BootStrapper.BuildUnityConfiguration
    Initialize Container
    RegisterMyAssemblies()

我希望’RegisterMyAssemblies’进程注册程序集的通配符列表,然后继续在每个单独的程序集中注册类型.有什么建议?

解决方法

您不应该尝试使用应用程序的主引导程序(组合根)来配置这些插件程序集,因为这很难做到.很难做到正确,因为主程序不知道要注册哪些类型,以及这些类型应该注册的生命周期.

相反,让每个插件程序集都有自己的bootstrapper方法,并将应用程序的容器实例传递到此插件引导程序.

例如,您可以在核心程序集中定义IBootstrapper接口,并让每个插件程序集实现此接口.例如:

public class System1Bootstrapper : IBootstrapper
{
    void IBootstrapper.Bootstrap(IUnityContainer container)
    {
        var conString = ConfigurationManager
            .ConnectionStrings["WebAppConnectionString"];

        if (conString == null)
        {
            throw new ApplicationException(
                    "The ConnectionString is not defined.");
        }

        // register all your components with the container here
        // it is NOT necessary to register your controllers
        container.RegisterType<ISystem1Entities,System1Entities>(
            new HierarchicalLifetimeManager(),new InjectionConstructor(conString.ConnectionString));

        container.RegisterType<ISystem1Service,System1Service>();
    }
}

在应用程序的组合根目录中,您现在可以简单地添加此代码来注册所有插件类型:

var pluginBootstrappers =
    from Assembly assembly in BuildManager.GetReferencedAssemblies()
    from type in assembly.GetExportedTypes()
    where typeof(IBootstrapper).IsAssignableFrom(type)
    select (IBootstrapper)Activator.CreateInstance(type);

pluginBootstrappers.ToList().ForEach(b => b.Bootstrap(container));

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读