接口,不能在Unity配置上构建

时间:2018-01-24 15:20:02

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

我在这个项目上使用Unity很麻烦。

错误是

  

当前类型Business.Interfaces.IPersonnelBusiness是一个   界面,不能构造。你错过了类型映射吗?

由于stackoverflow issue,我已将Unity更新到最新版本,我看到RegisterComponents已更改为延迟加载 这是全球性的asax:

src = src.convert('RGBA')

这是UnityConfig文件:

protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);

            // Unity settings
            //UnityConfig.RegisterComponents();

            // For logging
            //SetupSemanticLoggingApplicationBlock();
        }

谢谢大家

修改

这里是堆栈和抛出它的代码:

堆栈跟踪:

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

        /// <summary>
        /// Configured Unity Container.
        /// </summary>
        public static IUnityContainer Container
        {
            get
            {
                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)
        {
            // NOTE: To load from web.config uncomment the line below.
            // Make sure to add a Unity.Configuration to the using statements.
            // container.LoadConfiguration();

            // TODO: Register your type's mappings here.
            // container.RegisterType<IProductRepository, ProductRepository>();
            container = new UnityContainer();

            // Identity managment
            container.RegisterType<DbContext, ApplicationDbContext>(new HierarchicalLifetimeManager());
            container.RegisterType<UserManager<ApplicationUser>>(new HierarchicalLifetimeManager());
            container.RegisterType<IUserStore<ApplicationUser>, UserStore<ApplicationUser>>(new HierarchicalLifetimeManager());
            container.RegisterType<AccountController>(new InjectionConstructor());
            container.RegisterType<PersonnelController>(new InjectionConstructor());
            container.RegisterType<UsersAdminController>(new InjectionConstructor());

            // Business Layer
            container.RegisterType<ILogBusiness, LogBusiness>();
            container.RegisterType<IAnomalyBusiness, AnomalyBusiness>();
            container.RegisterType<ICockpitStatBusiness, CockpitStatsBusiness>();
            container.RegisterType<IDocumentBusiness, DocumentBusiness>();
            container.RegisterType<IEmailBusiness, EmailBusiness>();
            container.RegisterType<IMessageBusiness, MessageBusiness>();
            container.RegisterType<INatureBusiness, NatureBusiness>();
            container.RegisterType<IPersonnelBusiness, PersonnelBusiness>();
            container.RegisterType<ISAPBusiness, SAPBusiness>();

            // Set resolver
            DependencyResolver.SetResolver(new UnityDependencyResolver(container));

        }
    }

控制器:

[ResolutionFailedException: Resolution of the dependency failed, type = 'APPI.WEB.Controllers.HomeController', name = '(none)'.
Exception occurred while: while resolving.
Exception is: InvalidOperationException - The current type, APPI.Business.Interfaces.IPersonnelBusiness, is an interface and cannot be constructed. Are you missing a type mapping?
-----------------------------------------------
At the time of the exception, the container was: 
  Resolving APPI.WEB.Controllers.HomeController,(none)
  Resolving parameter 'personnelRepo' of constructor APPI.WEB.Controllers.HomeController(APPI.Business.Interfaces.IPersonnelBusiness personnelRepo, APPI.Business.Interfaces.IAnomalyBusiness anomalyRepo, APPI.Business.Interfaces.IDocumentBusiness docRepo, APPI.Business.Interfaces.IMessageBusiness msgRepo, APPI.Business.Interfaces.ICockpitStatBusiness cockpitStatRepo, APPI.Business.Interfaces.INatureBusiness natureRepo)
    Resolving APPI.Business.Interfaces.IPersonnelBusiness,(none)
]

由于

,在启动应用程序之前还会调用UnityActivator
public class HomeController : BaseController
    {

        private readonly IPersonnelBusiness _IPersonnelBusinessRepo;
        private readonly IAnomalyBusiness _IAnomalyBusinessRepo;
        private readonly IDocumentBusiness _IDocumentBusinessRepo;
        private readonly IMessageBusiness _IMessageBusinessRepo;
        private readonly ICockpitStatBusiness _ICockpitStatBusinessRepo;
        private readonly INatureBusiness _INatureBusinessRepo;

        // Unity inject references
        public HomeController(IPersonnelBusiness personnelRepo, IAnomalyBusiness anomalyRepo, IDocumentBusiness docRepo, 
            IMessageBusiness msgRepo, ICockpitStatBusiness cockpitStatRepo, INatureBusiness natureRepo)
        {
            _IPersonnelBusinessRepo = personnelRepo;
            _IAnomalyBusinessRepo = anomalyRepo;
            _IDocumentBusinessRepo = docRepo;
            _IMessageBusinessRepo = msgRepo;
            _ICockpitStatBusinessRepo = cockpitStatRepo;
            _INatureBusinessRepo = natureRepo;
        }
        public HomeController()
        {

        }

        public ActionResult Index()
        {
            return RedirectToActionPermanent("Cockpit", "Home");
        }

UnityActivator:

[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(APPI.WEB.UnityMvcActivator), "Start")]
[assembly: WebActivatorEx.ApplicationShutdownMethod(typeof(APPI.WEB.UnityMvcActivator), "Shutdown")]

1 个答案:

答案 0 :(得分:2)

正如评论中指出的那样,问题在于您在初始化程序中实例化了两个不同的容器:

    private static Lazy<IUnityContainer> container =
      new Lazy<IUnityContainer>(() =>
      {
          var container = new UnityContainer(); // <-- new container here
          RegisterTypes(container);
          return container;
      });

一旦进入RegisterTypes方法:

    public static void RegisterTypes(IUnityContainer container)
    {
        // NOTE: To load from web.config uncomment the line below.
        // Make sure to add a Unity.Configuration to the using statements.
        // container.LoadConfiguration();

        // TODO: Register your type's mappings here.
        // container.RegisterType<IProductRepository, ProductRepository>();
        container = new UnityContainer(); // <-- new container here

    ...

类型映射在RegisterTypes方法中添加到不同实例,而不是作为参数传入的容器。

为了使其正常工作,您应该在RegisterTypes中删除容器的实例化,以便它可以使用参数中传递的实例。

    public static void RegisterTypes(IUnityContainer container)
    {
        // NOTE: To load from web.config uncomment the line below.
        // Make sure to add a Unity.Configuration to the using statements.
        // container.LoadConfiguration();

        // TODO: Register your type's mappings here.
        // container.RegisterType<IProductRepository, ProductRepository>();
        // container = new UnityContainer(); // <-- Remove this

    ...