40

在我的引导程序中:

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

但后来我得到了错误:

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

我也试过

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

但没用

4

7 回答 7

46

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

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

例如,如果错误是
当前类型 xyznamespace.Imyinterfacename一个接口,无法构造。您是否缺少类型映射?"

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

 container.RegisterType<Imyinterfacename, myinterfaceimplclassname>();
于 2015-07-08T02:04:59.977 回答
20

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

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 接线都应该在您的 Bootstraper 中进行。你永远不应该container.Resolve<>在你的代码中使用调用。

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

于 2013-01-27T16:31:21.683 回答
9

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

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

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

IE

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)
    {

    }
    ...
}
于 2016-05-15T20:28:48.010 回答
0

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

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

第二步:在 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;
    }

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

        }

你完成了

于 2016-02-05T14:01:21.243 回答
0

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

于 2016-04-26T07:13:59.237 回答
0

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

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

于 2018-07-17T12:52:28.080 回答
0

以下代码将对您有所帮助

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;
}
于 2018-08-06T12:57:43.863 回答