web-dev-qa-db-de.com

Ausnahme ist: InvalidOperationException - Der aktuelle Typ ist eine Schnittstelle und kann nicht erstellt werden. Vermissen Sie eine Typenzuordnung?

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

im Code meines Controllers:

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

schweben auf mUnityContainer Ich sehe ISettingsManager ist SettingsManager zugeordnet.

aber dann bekomme ich den fehler:

Ausnahme ist: InvalidOperationException - Der aktuelle Typ ist ein Schnittstelle und kann nicht erstellt werden. Vermissen Sie eine Typenzuordnung?

Ich habe es auch versucht

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

aber nichts nützt 

29
Elad Benda

Sie verwenden fälschlicherweise Abhängigkeitsinjektion. Der richtige Weg ist, Ihre Controller die Abhängigkeiten übernehmen zu lassen, die sie benötigen, und dem Abhängigkeiten-Injektions-Framework die konkreten Instanzen zu überlassen:

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

Wie Sie in diesem Beispiel sehen können, weiß der Controller nichts über den Container. Und so soll es sein.

Die gesamte DI-Verkabelung sollte in Ihrem Bootstraper erfolgen. Sie sollten niemals container.Resolve<>-Aufrufe in Ihrem Code verwenden.

Was Ihren Fehler betrifft, ist die mUnityContainer, die Sie in Ihrem Controller verwenden, möglicherweise nicht dieselbe Instanz wie die in Ihrem Bootstraper erstellte. Da Sie jedoch keinen Containercode in Ihren Controllern verwenden sollten, sollte dies kein Problem mehr sein.

18
Darin Dimitrov

Nur für andere (wie ich), die möglicherweise mit dem obigen Fehler konfrontiert wurden. Die Lösung in einfachen Worten.

Möglicherweise haben Sie die Registrierung Ihrer Schnittstelle und Ihrer Klasse (die diese Schnittstelle implementiert) nicht in Ihrem Code registriert. 

z.B. wenn der Fehler ist
"Der aktuelle Typ xyznamespace. Imyinterfacename , ist eine Schnittstelle und kann nicht erstellt werden. Vermissen Sie eine Typzuordnung?"  

Dann müssen Sie die Klasse registrieren, die denImyinterfacenamein der UnityConfig -Klasse in derRegister-Methode implementiert. Code wie unten verwenden

 container.RegisterType<Imyinterfacename, myinterfaceimplclassname>();
29
Rama

In meinem Fall habe ich diesen Fehler erhalten, obwohl ich eine vorhandene Instanz für die betreffende Schnittstelle registriert habe.

Es stellte sich heraus, dass ich Unity in WebForms mithilfe des Pakets Unity.WebForms Nuget verwendet habe, und ich hatte einen Hierarchical Lifetime Manager für die Abhängigkeit angegeben, für die ich eine Instanz bereitstellte, jedoch einen Transient Lifetime Manager ein nachfolgender Typ, der vom vorherigen Typ abhing - normalerweise kein Problem -, aber mit Unity.WebForms arbeiten die Lifetime-Manager etwas anders ... Ihre injizierten Typen erfordern scheinbar einen hierarchischen Lifetime-Manager, für den jedoch ein neuer Container erstellt wird jede Webanfrage (wegen der Architektur von Webformularen, denke ich) ist hervorragend in diesem Beitrag erklärt.

Wie auch immer, ich habe es gelöst, indem ich bei der Registrierung einfach keinen Lifetime Manager für die Typen/Instanzen angegeben habe.

d.h.

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

wird

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

Damit der IMapper hier erfolgreich aufgelöst werden kann:

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

    }
    ...
}
7
Breeno

Der folgende Code wird für Sie hilfreich sein 

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

0
Balamurugan

Ich hatte dieses Problem und die Ursache war, dass ich das Microsoft.Owin.Host.SystemWeb NuGet-Paket nicht zu meinem Projekt hinzugefügt hatte. Obwohl der Code in meiner Startklasse korrekt war, wurde er nicht ausgeführt. 

Wenn Sie also versuchen, dieses Problem zu lösen, geben Sie im Code an der Stelle, an der Sie die Unity-Registrierungen durchführen, einen Haltepunkt an. Wenn Sie es nicht treffen, wird Ihre Abhängigkeitsinjektion nicht funktionieren. 

0
Dominic Cronin

In meinem Fall habe ich zwei unterschiedliche Zusammenhänge mit Unitofwork und Ioc-Container verwendet, daher sehe ich dieses Problem als zwingend an, während Service-Layer versuchen, das zweite Repository in DI zu injizieren. Der Grund ist, dass das exist-Modul andere Modulinstanzen und Container enthält, die einen Aufruf aus einem nicht zusammengesetzten neuen Repository erhalten sollen. Ich schreibe hier, für wen ich in meinen Schuhen bin 

0
dewelloper

Möglicherweise registrieren Sie die Controller nicht . Versuchen Sie es mit dem folgenden Code:

Schritt 1 . Schreiben Sie Ihre eigene Controller-Factory-Klasse ControllerFactory: DefaultControllerFactory durch Implementieren des Modellordners 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; }
        }
    }

Schritt 2: Regigster in BootStrap: InBuildUnityContainer-Methode

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

Schritt 3: In 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));

        }

Und du bist fertig

0
user5888468