C# 异常是: InvalidOperationException - 当前类型,是一个接口,不能被构造。您是否缺少类型映射?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14549156/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 12:14:07  来源:igfitidea点击:

Exception is: InvalidOperationException - The current type, is an interface and cannot be constructed. Are you missing a type mapping?

c#asp.net-mvcinversion-of-controlunity-container

提问by Elad Benda

In my bootstrapper:

在我的引导程序中:

namespace Conduit.Mam.ClientServices.Common.Initizliaer
{
    public static class Initializer
    {
        private static bool isInitialize;
        private static readonly object LockObj = new object();
        private static IUnityContainer defaultContainer = new UnityContainer();

        static Initializer()
        {
            Initialize();
        }

        public static void Initialize()
        {
            if (isInitialize)
                return;

            lock (LockObj)
            {
                IUnityContainer container = defaultContainer;

                //registering Unity for MVC
                DependencyResolver.SetResolver(new UnityDependencyResolver(container));

                //registering Unity for web API
                //  GlobalConfiguration.Configuration.DependencyResolver = new Unity.WebApi.UnityDependencyResolver(container);

                #region managers
                container.RegisterType<ISettingsManager, SettingsManager>();

                container.RegisterType<IMamDataManager, MamDataManager>();

                container.RegisterType<IAppsDataManager, AppsDataManager>();
                #endregion

                if (!isInitialize)
                {
                    isInitialize = true;
                }
            }
        }
    }
}

in my controller's code:

在我的控制器代码中:

ISettingsManager sm = mUnityContainer.Resolve<ISettingsManager>();

hovering on mUnityContainer I see ISettingsManageris mapped to SettingsManager

悬停在 mUnityContainer 我看到ISettingsManager映射到SettingsManager

but then I get the error:

但后来我得到了错误:

Exception is: InvalidOperationException - The current type, is an interface and cannot be constructed. Are you missing a type mapping?

异常是: InvalidOperationException - 当前类型,是一个接口,不能被构造。您是否缺少类型映射?

I have also tried

我也试过

ISettingsManager sm = (ISettingsManager)mUnityContainer.Resolve<>(typeof(ISettingsManager));

but no use

但没有用

采纳答案by Darin Dimitrov

You are incorrectly using Dependency Injection. The proper way is to have your controllers take the dependencies they need and leave to the dependency injection framework inject the concrete instances:

您错误地使用了依赖注入。正确的方法是让您的控制器获取他们需要的依赖项,并让依赖项注入框架注入具体实例:

public class HomeController: Controller
{
    private readonly ISettingsManager settingsManager;
    public HomeController(ISettingsManager settingsManager)
    {
        this.settingsManager = settingsManager;
    }

    public ActionResult Index()
    {
        // you could use the this.settingsManager here
    }
}

As you can see in this example the controller doesn't know anything about the container. And that's how it should be.

正如你在这个例子中看到的,控制器对容器一无所知。这就是它应该的样子。

All the DI wiring should happen in your Bootstraper. You should never use container.Resolve<>calls in your code.

所有 DI 接线都应该在 Bootstraper 中进行。你永远不应该container.Resolve<>在你的代码中使用调用。

As far as your error is concerned, probably the mUnityContaineryou are using inside your controller is not the same instance as the one constructed in your Bootstraper. But since you shouldn't be using any container code in your controllers, this shouldn't be a problem anymore.

就您的错误而言,mUnityContainer您在控制器中使用的实例可能与 Bootstraper 中构造的实例不同。但是由于您不应该在控制器中使用任何容器代码,这应该不再是问题。

回答by Ram

Just for others (like me) who might have faced the above error. The solution in simple terms.

仅适用于可能遇到上述错误的其他人(如我)。简单的解决方案。

You might have missed to register your Interface and class (which implements that inteface) registration in your code.

您可能错过了在代码中注册接口和类(实现该接口)的注册。

e.g if the error is
"The current type, xyznamespace. Imyinterfacename, is an interface and cannot be constructed. Are you missing a type mapping?"

如果错误是如
当前类型,xyznamespace。Imyinterfacename,是一个接口,不能构成。是否缺少类型映射?

Then you must register the class which implements the Imyinterfacenamein the UnityConfigclass in the Registermethod. using code like below

然后,你必须注册它实现了类ImyinterfacenameUnityConfig类中的注册方法。使用如下代码

 container.RegisterType<Imyinterfacename, myinterfaceimplclassname>();

回答by user5888468

May be You are not registering the Controllers. Try below code:

可能是您没有注册控制器。试试下面的代码:

Step 1. Write your own controller factory class ControllerFactory :DefaultControllerFactory by implementing defaultcontrollerfactory in models folder

步骤 1. 通过在模型文件夹中实现 defaultcontrollerfactory 编写您自己的控制器工厂类 ControllerFactory :DefaultControllerFactory

  public class ControllerFactory :DefaultControllerFactory
    {
    protected override IController GetControllerInstance(RequestContext         requestContext, Type controllerType)
        {
            try
            {
                if (controllerType == null)
                    throw new ArgumentNullException("controllerType");

                if (!typeof(IController).IsAssignableFrom(controllerType))
                    throw new ArgumentException(string.Format(
                        "Type requested is not a controller: {0}",
                        controllerType.Name),
                        "controllerType");

                return MvcUnityContainer.Container.Resolve(controllerType) as IController;
            }
            catch
            {
                return null;
            }

        }
        public static class MvcUnityContainer
        {
            public static UnityContainer Container { get; set; }
        }
    }

Step 2:Regigster it in BootStrap: inBuildUnityContainer method

第二步:在BootStrap中注册:inBuildUnityContainer方法

private static IUnityContainer BuildUnityContainer()
    {
      var container = new UnityContainer();

      // register all your components with the container here
      // it is NOT necessary to register your controllers

      // e.g. container.RegisterType<ITestService, TestService>();    
      //RegisterTypes(container);
      container = new UnityContainer();
      container.RegisterType<IProductRepository, ProductRepository>();


      MvcUnityContainer.Container = container;
      return container;
    }

Step 3: In Global Asax.

第 3 步:在全局 Asax 中。

protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
            AuthConfig.RegisterAuth();
            Bootstrapper.Initialise();
            ControllerBuilder.Current.SetControllerFactory(typeof(ControllerFactory));

        }

And you are done

你已经完成了

回答by Hamit YILDIRIM

In my case, I have used 2 different context with Unitofwork and Ioc container so i see this problem insistanting while service layer try to make inject second repository to DI. The reason is that exist module has containing other module instance and container supposed to gettng a call from not constractured new repository.. i write here for whome in my shooes

就我而言,我使用了 Unitofwork 和 Ioc 容器的 2 个不同上下文,因此当服务层尝试将第二个存储库注入 DI 时,我看到这个问题仍然存在。原因是存在模块包含其他模块实例和容器应该从未构造的新存储库中获取调用..我在这里写我的鞋子

回答by Breeno

In my case, I was getting this error despite registering an existing instance for the interface in question.

就我而言,尽管为相关接口注册了现有实例,但我仍收到此错误。

Turned out, it was because I was using Unity in WebForms by way of the Unity.WebFormsNuget package, and I had specified a Hierarchical Lifetime manager for the dependency I was providing an instance for, yet a Transient lifetime manager for a subsequent type that depended on the previous type - not usually an issue - but with Unity.WebForms, the lifetime managers work a little differently... your injected types seem to require a Hierarchical lifetime manager, but a new container is still created for every web request (because of the architecture of web forms I guess) as explained excellently in this post.

原来,这是因为我通过Unity.WebFormsNuget 包在 WebForms 中使用 Unity ,并且我为我提供实例的依赖项指定了一个分层生命周期管理器,但为后续类型指定了一个瞬态生命周期管理器取决于以前的类型 - 通常不是问题 - 但是对于 Unity.WebForms,生命周期管理器的工作方式略有不同......您注入的类型似乎需要一个分层生命周期管理器,但仍然为每个 Web 请求创建一个新容器(因为我猜是网络表单的架构),正如这篇文章中出色地解释的那样。

Anyway, I resolved it by simply not specifying a lifetime manager for the types/instances when registering them.

无论如何,我通过在注册它们时简单地不为类型/实例指定生命周期管理器来解决它。

i.e.

IE

container.RegisterInstance<IMapper>(MappingConfig.GetMapper(), new HierarchicalLifetimeManager());    
container.RegisterType<IUserContext, UserContext>(new TransientLifetimeManager());

becomes

变成

container.RegisterInstance<IMapper>(MappingConfig.GetMapper());
container.RegisterType<IUserContext, UserContext>();

So that IMapper can be resolved successfully here:

这样 IMapper 就可以在这里成功解析:

public class UserContext : BaseContext, IUserContext
{
    public UserContext(IMapper _mapper) : base(_mapper)
    {

    }
    ...
}

回答by Dominic Cronin

I had this problem, and the cause was that I had not added the Microsoft.Owin.Host.SystemWeb NuGet package to my project. Although the code in my startup class was correct, it was not being executed.

我遇到了这个问题,原因是我没有将 Microsoft.Owin.Host.SystemWeb NuGet 包添加到我的项目中。虽然我的启动类中的代码是正确的,但它并没有被执行。

So if you're trying to solve this problem, put a breakpoint in the code where you do the Unity registrations. If you don't hit it, your dependency injection isn't going to work.

因此,如果您正在尝试解决此问题,请在进行 Unity 注册的代码中放置一个断点。如果你不点击它,你的依赖注入就不会起作用。

回答by Balamurugan

Below code will be helpful for you

下面的代码对你有帮助

public static IUnityContainer Initialise(IUnityContainer container = null)
{
    if (container == null)
    {
        container = new UnityContainer();
    }
    container.RegisterType<ISettingsManager, SettingsManager>();
    container.Resolve<SettingsManager>();
    container.RegisterType<SettingsManagerController>(new InjectionProperty("_SettingManagerProvider", new ResolvedParameter<ISettingManager>()));
    return container;
}