web-dev-qa-db-fra.com

L'exception est la suivante: InvalidOperationException - Le type actuel est une interface et ne peut pas être construit. Il vous manque un mappage de type?

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

dans le code de mon contrôleur:

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

en survolant sur mUnityContainer, je vois que ISettingsManager est associé à SettingsManager

mais alors j'obtiens l'erreur:

L'exception est la suivante: InvalidOperationException - Le type actuel est un interface et ne peut pas être construit. Il vous manque un mappage de type?

J'ai aussi essayé

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

mais pas d'utilisation 

29
Elad Benda

Vous utilisez de manière incorrecte l’Injection de dépendance. La bonne façon de faire est que vos contrôleurs prennent les dépendances dont ils ont besoin et laissent au framework d’injection de dépendance injecter les instances concrètes:

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

Comme vous pouvez le voir dans cet exemple, le contrôleur ne sait rien du conteneur. Et c'est comme ça que ça devrait être.

Tout le câblage DI devrait avoir lieu dans votre Bootstraper. Vous ne devriez jamais utiliser d'appels container.Resolve<> dans votre code.

En ce qui concerne votre erreur, la mUnityContainer que vous utilisez dans votre contrôleur n’est probablement pas la même instance que celle construite dans votre Bootstraper. Mais comme vous ne devriez utiliser aucun code de conteneur dans vos contrôleurs, cela ne devrait plus être un problème.

18
Darin Dimitrov

Juste pour les autres (comme moi) qui auraient pu faire face à l'erreur ci-dessus. La solution en termes simples.

Vous avez peut-être manqué d'enregistrer votre interface et votre classe (qui implémente cette interface) dans votre code. 

par exemple si l'erreur est
"Le type actuel, xyznamespace. Imyinterfacename, est une interface et ne peut pas être construit. Il vous manque un mappage de type? " 

Vous devez ensuite enregistrer la classe qui implémente la Imyinterfacename dans la classe UnityConfig dans la méthode Register. en utilisant le code comme ci-dessous

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

Dans mon cas, je recevais cette erreur malgré l'enregistrement d'une instance existante pour l'interface en question.

En fait, c’est parce que j’utilisais Unity dans WebForms avec le package Unity.WebForms Nuget et que j’avais spécifié un gestionnaire Hierarchical Lifetime pour la dépendance pour laquelle je fournissais une instance, mais un gestionnaire de durée de vie transitoire pour un type ultérieur dépendant du type précédent - ce n'est généralement pas un problème - mais avec Unity.WebForms, les gestionnaires de durée de vie fonctionnent un peu différemment ... vos types injectés semblent nécessiter un gestionnaire de durée de vie hiérarchique, mais un nouveau conteneur est toujours créé pour chaque requête Web (en raison de l'architecture des formulaires Web, je suppose), comme expliqué de manière excellente dans cet article .

Quoi qu'il en soit, je l'ai résolu en ne spécifiant tout simplement pas de gestionnaire de durée de vie pour les types/instances lors de leur enregistrement.

c'est à dire.

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

devient

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

Pour qu'IMapper puisse être résolu avec succès ici:

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

    }
    ...
}
7
Breeno

Le code ci-dessous vous sera utile 

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

J'ai eu ce problème et la cause était que je n'avais pas ajouté le package Microsoft.Owin.Host.SystemWeb NuGet à mon projet. Bien que le code de ma classe de démarrage soit correct, il n'était pas exécuté. 

Donc, si vous essayez de résoudre ce problème, insérez un point d'arrêt dans le code où vous effectuez les enregistrements Unity. Si vous ne le faites pas, votre injection de dépendance ne fonctionnera pas. 

0
Dominic Cronin

Dans mon cas, j’ai utilisé 2 contextes différents avec Unitofwork et le conteneur Ioc, ce qui me pose problème alors que la couche service essaie de faire injecter un deuxième référentiel à DI. La raison en est que le module exist contient une autre instance de module et un conteneur censés recevoir un appel d'un nouveau référentiel non construit. Je vous écris ici pour savoir ce qui se passe dans mes shooes 

0
dewelloper

Vous n’enregistrez peut-être pas les contrôleurs ..__ Essayez le code ci-dessous:

Étape 1 . Écrivez votre propre classe d'usine de contrôleur ControllerFactory: DefaultControllerFactory en implémentant le dossier defaultcontrollerfactoryin

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

Étape 2: Enregistrez-le dans BootStrap: méthode 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;
    }

Étape 3: Dans 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));

        }

Et vous avez terminé

0
user5888468