繁体   English   中英

构造函数参数的统一性和依赖性

[英]Unity and dependency with constructor params

当我尝试使用带有接口的类时遇到Unity问题,该类的实现带有4个参数。

这里是错误堆栈跟踪:

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)
↵"

还有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)
        //});
    }

并执行IMediation

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

我尝试了几种配置,背后的代码和web.config,但在上次解决(调解)时遇到了相同的错误。

那么,如何注册一个带有参数接口的类呢?

谢谢你的帮助。

编辑:工作代码

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

您对Unity的使用有点委婉。 当您进行注册时,几乎应该只进行注册,而不是进行注册/解决/“使用产品进行注册”等。您希望将分辨率和类实例化推迟到最新的负责任时刻。

另外,当注册的参数不起作用时,应使用ParameterOverride来覆盖为特定情况设置的参数。 您可以注册它们。 这是我的处理方式:

(出于可读性考虑,我在所有地方都删除了“ Okapi.Models”和“ Keolis.Mediation”。)

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

尚未测试代码,因为它具有太多的依赖关系,但是它应该可以工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM