异常是: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));
但没有用
仅适用于可能遇到上述错误的其他人(如我)。 简单来说,解决方案。
您可能错过了在代码中注册接口和类(实现该接口)注册。
例如,如果错误是
"当前类型,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;
}