Подтвердить что ты не робот

Исключение: InvalidOperationException - текущий тип, является интерфейсом и не может быть сконструирован. Вам не хватает картографирования типов?

В моем загрузчике:

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

но не использовать

4b9b3361

Ответ 1

Вы неправильно используете Injection Dependency. Правильный способ состоит в том, чтобы ваши контроллеры принимали нужные им зависимости и уходили в инфраструктуру инъекции зависимостей, введя конкретные экземпляры:

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. Но так как вы не должны использовать какой-либо код контейнера в своих контроллерах, это больше не должно быть проблемой.

Ответ 2

Просто для других (таких как я), которые могли столкнуться с вышеупомянутой ошибкой. Решение в простых терминах.

Возможно, вы пропустили регистрацию своего интерфейса и класса (который реализует эту внутреннюю) регистрацию в вашем коде.

например, если ошибка "Текущий тип, xyznamespace. Imyinterfacename, является интерфейсом и не может быть сконструирован. Вам не хватает сопоставления типов? "

Затем вы должны зарегистрировать класс, который реализует Imyinterfacename в классе UnityConfig в методе Реестр. используя следующий код

 container.RegisterType<Imyinterfacename, myinterfaceimplclassname>();

Ответ 3

В моем случае я получал эту ошибку, несмотря на регистрацию существующего экземпляра для рассматриваемого интерфейса.

Оказалось, это потому, что я использовал Unity в WebForms через пакет Nuget Unity.WebForms, и я определил Hierarchical Lifetime Manager для зависимости, для которой я предоставлял экземпляр, и все же Transient Life Manager для последующего типа, который зависит от предыдущего типа - обычно это не проблема, - но с Unity.WebForms менеджеры времени жизни работают немного по-другому... Ваши внедренные типы, похоже, требуют иерархического менеджера времени жизни, но новый контейнер по-прежнему создается для каждого веб-запроса ( из-за архитектуры веб-форм, я думаю), как превосходно объяснено в этом посте.

Во всяком случае, я решил это, просто не указав менеджер времени жизни для типов/экземпляров при их регистрации.

т.е.

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

    }
    ...
}

Ответ 4

Может быть, вы не регистрируете контроллеры. Попробуйте ввести код:

Шаг 1. Напишите свой собственный контроллер класса factory ControllerFactory: DefaultControllerFactory путем реализации 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: зарегистрируйте его в 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: В Global 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));

        }

И вы закончили

Ответ 5

В моем случае я использовал 2 разных контекста с контейнером Unitofwork и Ioc, поэтому я вижу, что эта проблема настойчива, пока уровень сервиса пытается сделать второй репозиторий для DI. Причина в том, что существующий модуль содержит другой экземпляр модуля и контейнер, предназначенный для получения вызова из непереработанного нового репозитория. Я пишу здесь для кого-то в моих шагах

Ответ 6

У меня была эта проблема, и причина была в том, что я не добавил пакет Microsoft.Owin.Host.SystemWeb NuGet в свой проект. Хотя код в моем классе запуска был правильным, он не выполнялся.

Поэтому, если вы пытаетесь решить эту проблему, поставьте точку останова в коде, где вы регистрируетесь в Unity. Если вы не нажмете это, ваша инъекция зависимости не сработает.

Ответ 7

Ниже код будет полезен для вас

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