Unity DI自定义汇编的自动注册

时间:2016-09-14 20:16:00

标签: c# asp.net-mvc dependency-injection unity-container

我正在尝试使用Unity Registration by Convention功能。 我无法弄清楚如何从特定的程序集/项目文件注册文件结尾“存储库”。

container.RegisterTypes(
       AllClasses.FromAssembliesInBasePath(),
       WithMappings.FromMatchingInterface,
       WithName.Default,
       WithLifetime.ContainerControlled);

我在MSDN博客(https://blogs.msdn.microsoft.com/agile/2013/03/12/unity-configuration-registration-by-convention/)帖子中找到了这个例子,据我了解,这将搜索所有项目/程序集,并查找默认的命名约定文件Class和IClass。

我的解决方案中有一个名为CManager.Repository的项目,其存储库文件以* Repository结尾。它们是自动注册的。

任何提示或帮助?

2 个答案:

答案 0 :(得分:3)

对于统一的自动注册,最好将存储库项目中的InterfacesRepositories文件夹与正确的命名约定分开。
enter image description here

如果您在单个项目下拥有所有存储库,则无需扫描所有程序集。这应该在项目CManager.Repository

下注册所有存储库
  public static class UnityConfig
   {
     public static void RegisterComponents()
      {
        var container = new UnityContainer();
        var repositoryAssembly = AppDomain.CurrentDomain.GetAssemblies()
            .First(a => a.FullName == "CManager.Repository, Version=X.X.X.X, Culture=neutral, PublicKeyToken=null"); 

        container.RegisterTypes(repositoryAssembly.GetTypes(),
            WithMappings.FromMatchingInterface,
            WithName.Default,
            WithLifetime.ContainerControlled);      

        container.RegisterType<ApplicationDbContext>(new PerResolveLifetimeManager());
       // ................ register other things is needed
        DependencyResolver.SetResolver(new UnityDependencyResolver(container));
     }
  } 

我们必须在应用程序启动上注册统一组件,传统上在Global.asax.cs文件中。因此,将UnityConfig.cs文件放在App_Start文件夹下的启动项目中。

public class MvcApplication : HttpApplication
{
    protected void Application_Start()
    {
        UnityConfig.RegisterComponents();
        AreaRegistration.RegisterAllAreas();
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);            
    }      
}

并确保其他项目与启动项目链接

答案 1 :(得分:-2)

这对我来说是一个企业web-api,我已经工作了好几个月了。它有一个n层架构,其数据层具有.cs文件,以&#39; Repository&#39;结尾。虽然我同意其他帖子的界面应该分开,但在我的web-api中,它们并没有以这种方式实现。

using System;
using System.Web.Http;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;
using Unity.WebApi;

namespace Blah.Endpoints.App_Start
{
    /// <summary>
    /// Specifies the Unity configuration for the main container.
    /// </summary>
    public static class UnityConfig
    {
        public static void RegisterComponents()
        {
            var container = new UnityContainer();

            // register all your components with the container here
            // it is NOT necessary to register your controllers
            RegisterTypes(container);
            // e.g. container.RegisterType<ITestService, TestService>();

            GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(container);
        }

        #region Unity Container
        private static Lazy<IUnityContainer> container = new Lazy<IUnityContainer>(() =>
        {
            var container = new UnityContainer();
            RegisterTypes(container);
            return container;
        });

        /// <summary>
        /// Gets the configured Unity container.
        /// </summary>
        public static IUnityContainer GetConfiguredContainer()
        {
            return container.Value;
        }
        #endregion

        /// <summary>Registers the type mappings with the Unity container.</summary>
        /// <param name="container">The unity container to configure.</param>
        /// <remarks>There is no need to register concrete types such as controllers or API controllers (unless you want to 
        /// change the defaults), as Unity allows resolving a concrete type even if it was not previously registered.</remarks>
        public static void RegisterTypes(IUnityContainer container)
        {

            container.RegisterTypes(AllClasses.FromLoadedAssemblies(),
                WithMappings.FromMatchingInterface,
                WithName.Default,
                null,                //WithLifetime IF we want to change the lifetime aspect aka Singletons 
                null,//GetMembers,
                false
                );
        }


    }
}

此设置通常适用于我的团队。有时我们仍然会在没有明显原因的情况下获得出现统一错误的类对于那些我们做这样的事情;

public class WcfServiceFactory : UnityServiceHostFactory
    {
        protected override void ConfigureContainer(IUnityContainer container)
        {
            //Attach hook for AOP attributes
            container.AddNewExtension<Interception>();

            // register all your components with the container here
            // container
            //    .RegisterType<IService1, Service1>()
            //    .RegisterType<DataContext>(new HierarchicalLifetimeManager());

            container.RegisterTypes(AllClasses.FromLoadedAssemblies(),
                WithMappings.FromMatchingInterface,
                WithName.Default,
                null,                //WithLifetime IF we want to change the lifetime aspect aka Singletons 
                GetMembers,
                false
                );

            container.RegisterType<IPaymentService, PaymentService>();
            container.RegisterType<IPaymentManager, PaymentManager>();
            container.RegisterType<IPaymentMethodRepository, PaymentMethodRepository>();
            container.RegisterType<IPaymentWithdrawScheduleRepository, PaymentWithdrawScheduleRepository>();
            container.RegisterType<IPaymentPreEnrollmentRepository, PaymentPreEnrollmentRepository>();
            container.RegisterType<ISharedLoanDataRepository<tblPaymentMethod>, SharedLoanDataRepository<tblPaymentMethod>>();
            container.RegisterType<ISharedLoanDataRepository<tblPaymentWithdrawSchedule>, SharedLoanDataRepository<tblPaymentWithdrawSchedule>>();
            container.RegisterType<IPaymentWithdrawScheduleOffSetTypeRepository, PaymentWithdrawScheduleOffSetTypeRepository>();
            container.RegisterType<IPaymentMethodTypeRepository, PaymentMethodTypeRepository>();
            container.RegisterType<IPaymentWithdrawScheduleFrequencyTypeRepository, PaymentWithdrawScheduleFrequencyTypeRepository>();
            container.RegisterType<IPaymentCustomerNotificationRepository, PaymentCustomerNotificationRepository>();
            container.RegisterType<ITraceLogger, TraceLogger>();
            container.RegisterType<IPaymentWithdrawScheduleCancelReasonRepository, PaymentWithdrawScheduleCancelReasonRepository>();
        }

        private IEnumerable<InjectionMember> GetMembers(Type type)
        {
            var list = new List<InjectionMember>();
            list.Add(new InterceptionBehavior<PolicyInjectionBehavior>(type.ToString()));
            list.Add(new Interceptor<InterfaceInterceptor>(type.ToString()));
            return list;
        }
    } 

我希望这会有所帮助

问候。