0

I have an issue on Unity when I try to use a class with interface, that have an implementation with 4 parameters.

Here the error stack trace :

Resolution of the dependency failed, type = "Keolis.ODM.Controllers.TypeTacheApiController", name = "(none)".
↵Exception occurred while: while resolving.
↵Exception is: InvalidOperationException - The type String cannot be constructed. You must configure the container to supply this value.
↵-----------------------------------------------
↵At the time of the exception, the container was:
↵
↵  Resolving Keolis.ODM.Controllers.TypeTacheApiController,(none)
↵  Resolving parameter "typeTacheService" of constructor Keolis.ODM.Controllers.TypeTacheApiController(Keolis.ODM.Business.ITypeTacheService typeTacheService)
↵    Resolving Keolis.ODM.Business.TypeTacheService,(none) (mapped from Keolis.ODM.Business.ITypeTacheService, (none))
↵    Resolving parameter "mediation" of constructor Keolis.ODM.Business.TypeTacheService(Keolis.Mediation.IMediation mediation, Keolis.ODM.Models.Repositories.ITypeTacheRepository typeTacheRepository, Keolis.Okapi.Models.Repositories.ITypeTacheRepository typeTacheOkapiRepository)
↵      Resolving Keolis.Mediation.WebService.Mediation,(none) (mapped from Keolis.Mediation.IMediation, (none))
↵      Resolving parameter "profilOkapiRepository" of constructor Keolis.Mediation.WebService.Mediation(Keolis.Okapi.Models.Repositories.IProfilOkapiRepository profilOkapiRepository, Keolis.Okapi.Models.Repositories.ISocieteOkapiRepository societeOkapiRepository, Keolis.Okapi.Models.Repositories.ICentreOkapiRepository centreOkapiRepository, Keolis.Okapi.Models.Repositories.IUtilisateurOkapiRepository utilisateurOkapiRepository)
↵        Resolving Keolis.Okapi.Models.Repositories.ProfilOkapiRepository,(none) (mapped from Keolis.Okapi.Models.Repositories.IProfilOkapiRepository, (none))
↵        Resolving parameter "serveur" of constructor Keolis.Okapi.Models.Repositories.ProfilOkapiRepository(System.String serveur, System.String catalog, System.String user, System.String pass)
↵          Resolving System.String,(none)
↵"

And the UnityConfig

    public static void RegisterTypes(IUnityContainer container)
    {
        // NOTE: To load from web.config uncomment the line below. Make sure to add a Microsoft.Practices.Unity.Configuration to the using statements.
        container.LoadConfiguration();

        var repository = container.Resolve<ILocalDatabaseService>();
        var referentielLocalDatabase = repository.GetRsh();

        container.RegisterType<Okapi.Models.Repositories.ITypeHeureRepository, Okapi.Models.Repositories.TypeHeureRepository>();
        container.Resolve<Okapi.Models.Repositories.ITypeHeureRepository>(new ResolverOverride[] {
            new ParameterOverride("serveur", referentielLocalDatabase.Serveur),
            new ParameterOverride("catalog", referentielLocalDatabase.Base),
            new ParameterOverride("user", referentielLocalDatabase.User),
            new ParameterOverride("pass", referentielLocalDatabase.Password)
            });

        container.RegisterType<Okapi.Models.Repositories.ITypeTacheRepository, Okapi.Models.Repositories.TypeTacheRepository>();
        container.Resolve<Okapi.Models.Repositories.ITypeTacheRepository>(new ResolverOverride[] {
            new ParameterOverride("serveur", referentielLocalDatabase.Serveur),
            new ParameterOverride("catalog", referentielLocalDatabase.Base),
            new ParameterOverride("user", referentielLocalDatabase.User),
            new ParameterOverride("pass", referentielLocalDatabase.Password)
            });

        container.RegisterType<Okapi.Models.Repositories.IUtilisateurOkapiRepository, Okapi.Models.Repositories.UtilisateurOkapiRepository>();
        var utilisateur = container.Resolve<Okapi.Models.Repositories.IUtilisateurOkapiRepository>(new ResolverOverride[] {
            new ParameterOverride("serveur", referentielLocalDatabase.Serveur),
            new ParameterOverride("catalog", referentielLocalDatabase.Base),
            new ParameterOverride("user", referentielLocalDatabase.User),
            new ParameterOverride("pass", referentielLocalDatabase.Password)
            });

        container.RegisterType<Okapi.Models.Repositories.ISocieteOkapiRepository, Okapi.Models.Repositories.SocieteOkapiRepository>();
        var societe = container.Resolve<Okapi.Models.Repositories.ISocieteOkapiRepository>(new ResolverOverride[] {
            new ParameterOverride("serveur", referentielLocalDatabase.Serveur),
            new ParameterOverride("catalog", referentielLocalDatabase.Base),
            new ParameterOverride("user", referentielLocalDatabase.User),
            new ParameterOverride("pass", referentielLocalDatabase.Password)
            });

        container.RegisterType<Okapi.Models.Repositories.IProfilOkapiRepository, Okapi.Models.Repositories.ProfilOkapiRepository>();
        var profil = container.Resolve<Okapi.Models.Repositories.IProfilOkapiRepository>(new ResolverOverride[] {
            new ParameterOverride("serveur", referentielLocalDatabase.Serveur),
            new ParameterOverride("catalog", referentielLocalDatabase.Base),
            new ParameterOverride("user", referentielLocalDatabase.User),
            new ParameterOverride("pass", referentielLocalDatabase.Password)
            });

        container.RegisterType<Okapi.Models.Repositories.ICentreOkapiRepository, Okapi.Models.Repositories.CentreOkapiRepository>();
        var centre = container.Resolve<Okapi.Models.Repositories.ICentreOkapiRepository>(new ResolverOverride[] {
            new ParameterOverride("serveur", referentielLocalDatabase.Serveur),
            new ParameterOverride("catalog", referentielLocalDatabase.Base),
            new ParameterOverride("user", referentielLocalDatabase.User),
            new ParameterOverride("pass", referentielLocalDatabase.Password)
            });

        container.RegisterType<Okapi.Models.Repositories.IBuildVersionOkapiRepository, Okapi.Models.Repositories.BuildVersionOkapiRepository>();
        container.Resolve<Okapi.Models.Repositories.IBuildVersionOkapiRepository>(new ResolverOverride[] {
            new ParameterOverride("serveur", referentielLocalDatabase.Serveur),
            new ParameterOverride("catalog", referentielLocalDatabase.Base),
            new ParameterOverride("user", referentielLocalDatabase.User),
            new ParameterOverride("pass", referentielLocalDatabase.Password)
            });

        container.RegisterType<Keolis.Mediation.IMediation, Keolis.Mediation.WebService.Mediation>(new InjectionConstructor(
            new Okapi.Models.Repositories.ProfilOkapiRepository(referentielLocalDatabase.Serveur, referentielLocalDatabase.Base, referentielLocalDatabase.User, referentielLocalDatabase.Password),
            new Okapi.Models.Repositories.SocieteOkapiRepository(referentielLocalDatabase.Serveur, referentielLocalDatabase.Base, referentielLocalDatabase.User, referentielLocalDatabase.Password),
            new Okapi.Models.Repositories.CentreOkapiRepository(referentielLocalDatabase.Serveur, referentielLocalDatabase.Base, referentielLocalDatabase.User, referentielLocalDatabase.Password),
            new Okapi.Models.Repositories.UtilisateurOkapiRepository(referentielLocalDatabase.Serveur, referentielLocalDatabase.Base, referentielLocalDatabase.User, referentielLocalDatabase.Password)
            ));

        //container.RegisterType<Keolis.Mediation.IMediation, Keolis.Mediation.WebService.Mediation>(new InjectionConstructor(
        //    profil, societe, centre, utilisateur));

        //container.Resolve<Keolis.Mediation.IMediation>(new ResolverOverride[] {
        //    new ParameterOverride("profilOkapiRepository", profil),
        //    new ParameterOverride("societeOkapiRepository", societe),
        //    new ParameterOverride("centreOkapiRepository", centre),
        //    new ParameterOverride("utilisateurOkapiRepository", utilisateur)
        //});
    }

And the implementation of IMediation

 public Mediation(IProfilOkapiRepository profilOkapiRepository,
        ISocieteOkapiRepository societeOkapiRepository,
        ICentreOkapiRepository centreOkapiRepository,
        IUtilisateurOkapiRepository utilisateurOkapiRepository)
    {
        _profilOkapiRepository = profilOkapiRepository;
        _societeOkapiRepository = societeOkapiRepository;
        _centreOkapiRepository = centreOkapiRepository;
        _utilisateurOkapiRepository = utilisateurOkapiRepository;
        _deser = new Deserializer();
    }

I have tried several config, code behind and web.config, but ever the same errors on last resolve (Mediation).

So, how to register a class that have interface with parameters ?

Thanks for your help.

EDIT : Working code

public static void RegisterTypes(IUnityContainer container)
{
    // NOTE: To load from web.config uncomment the line below. Make sure to add a Microsoft.Practices.Unity.Configuration to the using statements.
    container.LoadConfiguration();

    var repository = container.Resolve<ILocalDatabaseService>();
    var referentielLocalDatabase = repository.GetRsh();

    // This says "if you ever need need a string called 'xxxx', get that one."
    container.RegisterInstance<string>("serveur", referentielLocalDatabase.Serveur);
    container.RegisterInstance<string>("catalog", referentielLocalDatabase.Base);
    container.RegisterInstance<string>("user", referentielLocalDatabase.User);
    container.RegisterInstance<string>("pass", referentielLocalDatabase.Password);

    // Here it says "Find a constructor that needs 4 strings, and use
    // these registered string.
    container.RegisterType<Okapi.Models.Repositories.ITypeHeureRepository, Okapi.Models.Repositories.TypeHeureRepository>(
        new InjectionConstructor(
            new ResolvedParameter<string>("serveur"),
            new ResolvedParameter<string>("catalog"),
            new ResolvedParameter<string>("user"),
            new ResolvedParameter<string>("pass"))
        );

    container.RegisterType<Okapi.Models.Repositories.ITypeTacheRepository, Okapi.Models.Repositories.TypeTacheRepository>(
        new InjectionConstructor(
            new ResolvedParameter<string>("serveur"),
            new ResolvedParameter<string>("catalog"),
            new ResolvedParameter<string>("user"),
            new ResolvedParameter<string>("pass"))
        );

    container.RegisterType<Okapi.Models.Repositories.IUtilisateurOkapiRepository, Okapi.Models.Repositories.UtilisateurOkapiRepository>(
        new InjectionConstructor(
            new ResolvedParameter<string>("serveur"),
            new ResolvedParameter<string>("catalog"),
            new ResolvedParameter<string>("user"),
            new ResolvedParameter<string>("pass"))
        );

    container.RegisterType<Okapi.Models.Repositories.ISocieteOkapiRepository, Okapi.Models.Repositories.SocieteOkapiRepository>(
        new InjectionConstructor(
            new ResolvedParameter<string>("serveur"),
            new ResolvedParameter<string>("catalog"),
            new ResolvedParameter<string>("user"),
            new ResolvedParameter<string>("pass"))
        );

    container.RegisterType<Okapi.Models.Repositories.IProfilOkapiRepository, Okapi.Models.Repositories.ProfilOkapiRepository>(
        new InjectionConstructor(
            new ResolvedParameter<string>("serveur"),
            new ResolvedParameter<string>("catalog"),
            new ResolvedParameter<string>("user"),
            new ResolvedParameter<string>("pass"))
        );

    container.RegisterType<Okapi.Models.Repositories.ICentreOkapiRepository, Okapi.Models.Repositories.CentreOkapiRepository>(
        new InjectionConstructor(
            new ResolvedParameter<string>("serveur"),
            new ResolvedParameter<string>("catalog"),
            new ResolvedParameter<string>("user"),
            new ResolvedParameter<string>("pass"))
        );

    container.RegisterType<Okapi.Models.Repositories.IBuildVersionOkapiRepository, Okapi.Models.Repositories.BuildVersionOkapiRepository>(
        new InjectionConstructor(
            new ResolvedParameter<string>("serveur"),
            new ResolvedParameter<string>("catalog"),
            new ResolvedParameter<string>("user"),
            new ResolvedParameter<string>("pass"))
        );

    // Here it says "For IMediation, use the Mediation class".
    // The constructor you've shown us will required the other interfaces and
    // the container will be like "I know how to create a class of all of
    // these interfaces. I'll do that!"
    container.RegisterType<Mediation.IMediation, Mediation.WebService.Mediation>();            
}
1
  • Did you try register your 4 input interfaces with a register names, simplify your IMediation registration: container.RegisterType<Keolis.Mediation.IMediation, Keolis.Mediation.WebService.Mediation>() and inject in constructor a objects by register names public Mediation([Dependency(SomeRegisterName)]IProfilOkapiRepository profilOkapiRepository,...)? Commented Jun 14, 2017 at 17:48

1 Answer 1

1

You're kinda (euphemism) using Unity wrong. When you do the registration, you should almost always do registrations only, not register/resolve/"use the product to register" etc. You want to defer the resolution, and the class instantiation, to the latest responsible moment.

Also, using ParameterOverride should be used to override parameters you'd have set for a specific case, when the ones you registered do not work. In your case, you could register them. Here's how I'd do it:

(I removed the "Okapi.Models." and "Keolis.Mediation." everywhere for readability.)

public static void RegisterTypes(IUnityContainer container)
{
    var repository = container.Resolve<ILocalDatabaseService>();
    var referentielLocalDatabase = repository.GetRsh();

    // This says "if you ever need need a string called 'xxxx', get that one."
    container.RegisterInstance<string>("serveur", referentielLocalDatabase.Serveur);
    container.RegisterInstance<string>("catalog", referentielLocalDatabase.Base);
    container.RegisterInstance<string>("user", referentielLocalDatabase.User);
    container.RegisterInstance<string>("pass", referentielLocalDatabase.Password);

    // Here it says "Find a constructor that needs 4 strings, and use
    // these registered string.
    container.RegisterType<Repositories.ITypeHeureRepository, Repositories.TypeHeureRepository>(
        new ParameterResolve<string>("serveur"),
        new ParameterResolve<string>("catalog"),
        new ParameterResolve<string>("user"),
        new ParameterResolve<string>("pass"));

    container.RegisterType<Repositories.ITypeTacheRepository, Repositories.TypeTacheRepository>(
        new ParameterResolve<string>("serveur"),
        new ParameterResolve<string>("catalog"),
        new ParameterResolve<string>("user"),
        new ParameterResolve<string>("pass"));

    container.RegisterType<Repositories.IUtilisateurOkapiRepository, Repositories.UtilisateurOkapiRepository>(
        new ParameterResolve<string>("serveur"),
        new ParameterResolve<string>("catalog"),
        new ParameterResolve<string>("user"),
        new ParameterResolve<string>("pass"));

    container.RegisterType<Repositories.ISocieteOkapiRepository, Repositories.SocieteOkapiRepository>(
        new ParameterResolve<string>("serveur"),
        new ParameterResolve<string>("catalog"),
        new ParameterResolve<string>("user"),
        new ParameterResolve<string>("pass"));

    container.RegisterType<Repositories.IProfilOkapiRepository, Repositories.ProfilOkapiRepository>(
        new ParameterResolve<string>("serveur"),
        new ParameterResolve<string>("catalog"),
        new ParameterResolve<string>("user"),
        new ParameterResolve<string>("pass"));

    container.RegisterType<Repositories.ICentreOkapiRepository, Repositories.CentreOkapiRepository>(
        new ParameterResolve<string>("serveur"),
        new ParameterResolve<string>("catalog"),
        new ParameterResolve<string>("user"),
        new ParameterResolve<string>("pass"));

    container.RegisterType<Repositories.IBuildVersionOkapiRepository, Repositories.BuildVersionOkapiRepository>(
        new ParameterResolve<string>("serveur"),
        new ParameterResolve<string>("catalog"),
        new ParameterResolve<string>("user"),
        new ParameterResolve<string>("pass"));

    // Here it says "For IMediation, use the Mediation class".
    // The constructor you've shown us will required the other interfaces and
    // the container will be like "I know how to create a class of all of
    // these interfaces. I'll do that!"
    container.RegisterType<IMediation, WebService.Mediation>();
}

Haven't tested the code because it has too many dependencies, but it should work.

Sign up to request clarification or add additional context in comments.

2 Comments

Working great ! I understand better this concept now. I have edited my question to add the working code, if you want update your answer.
I'm glad it helped. You didn't have to update your question though. You checking the "Accept Answer" button already flagged, for the other people that would have the same question (more or less), that this was what fixed it for you. :-)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.