异常是:InvalidOperationException - 当前类型,是一个接口,无法构造.您是否缺少类型映射

本文关键字:类型 映射 是否 接口 InvalidOperationException 异常 一个 | 更新日期: 2023-09-27 17:56:08

在我的引导程序中:

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;
                }
            }
        }
    }
}

在我的控制器代码中:

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

将鼠标悬停在mUnityContainer上,我看到ISettingsManager映射到SettingsManager

但随后我收到错误:

异常

是:无效操作异常 - 当前类型,是 接口,无法构造。是否缺少类型映射?

我也试过

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

但没有用

异常是:InvalidOperationException - 当前类型,是一个接口,无法构造.您是否缺少类型映射

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

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

例如,如果错误是
"当前类型,xyz命名空间。Imyinterfacename,是一个接口,不能构造。是否缺少类型映射?"

然后,您必须在 Register 方法中注册在 UnityConfig 类中实现 Imyinterfacename 的类。 使用如下所示的代码

 container.RegisterType<Imyinterfacename, myinterfaceimplclassname>();

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

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
    }
}

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

所有 DI 连接都应在您的引导程序中进行。切勿在代码中使用container.Resolve<>调用。

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

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

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

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

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

成为

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

以便可以在此处成功解析 IMapper:

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

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

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

第 1 步。编写自己的控制器工厂类ControllerFactory :D efaultControllerFactory 通过实现 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; }
        }
    }

第 2 步:在引导程序中注册它: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;
    }

第 3 步:在全球阿萨克斯。

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));
        }

你完成了

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

因此,如果要解决此问题,请在执行 Unity 注册的代码中放置一个断点。如果你不击中它,你的依赖注入将不起作用。

下面的代码会对你有所帮助

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;
}