1

J'utilise l'unité comme conteneur IoC. J'essaye d'implémenter un type de IProviderRepository. L'implémentation concrète a un constructeur qui accepte un type d'IRepository. Lorsque je supprime le paramètre constructeur de l'implémentation concrète, tout fonctionne correctement. Je suis sûr que le conteneur est correctement câblé. Lorsque je tente de créer l'objet concret avec le constructeur que je reçois l'erreur suivante:Création d'unités et d'objets

"The current build operation (build key Build Key[EMRGen.Infrastructure.Data.IRepository 1[EMRGen.Model.Provider.Provider], null]) failed: The current type, EMRGen.Infrastructure.Data.IRepository 1[EMRGen.Model.Provider.Provider], is an interface and cannot be constructed. Are you missing a type mapping? (Strategy type BuildPlanStrategy, index 3)".

Est-il possible d'obtenir la fonctionnalité mention ci-dessus avec l'unité? A savoir que Unity déduit un type concret de l'interface et injecte aussi le constructeur du type concret avec l'objet concret approprié basé sur les paramètres du constructeur. Voici un exemple de mes types définis dans Unity et une liste de classes squelette pour ce que je veux réaliser. IProviderRepository est implémenté par ProviderRepository qui a un constructeur qui attend un type d'IRepository.

<typeAlias alias="ProviderRepositoryInterface" type="EMRGen.Model.Provider.IProviderRepository, EMRGen.Model" /> 
<typeAlias alias="ProviderRepositoryConcrete" type="EMRGen.Infrastructure.Repositories.Providers.ProviderRepository, EMRGen.Infrastructure.Repositories" /> 
<typeAlias alias="ProviderGenericRepositoryInterface" type="EMRGen.Infrastructure.Data.IRepository`1[[EMRGen.Model.Provider.IProvider, EMRGen.Model]], EMRGen.Infrastructure" /> 
<typeAlias alias="ProviderGenericRepositoryConcrete" type="EMRGen.Infrastructure.Repositories.EntityFramework.ApplicationRepository`1[[EMRGen.Model.Provider.Provider, EMRGen.Model]], EMRGen.Infrastructure.Repositories" /> 
<!-- Provider Mapping--> 
<typeAlias alias="ProviderInterface" type="EMRGen.Model.Provider.IProvider, EMRGen.Model" /> 
<typeAlias alias="ProviderConcrete" type="EMRGen.Model.Provider.Doctor, EMRGen.Model" /> 

Illustrer l'appel étant fait dans ma classe:

public class PrescriptionService 
{ 
    PrescriptionService() 
    { 
     IUnityContainer uc = UnitySingleton.Instance.Container; 
     UnityServiceLocator unityServiceLocator = new UnityServiceLocator(uc); 
     ServiceLocator.SetLocatorProvider(() => unityServiceLocator); 
     IProviderRepository pRepository = 
      ServiceLocator.Current.GetInstance<IProviderRepository>(); 
    } 
} 

public class GenericRepository<IProvider> : IRepository<IProvider> 
{ 
} 

public class ProviderRepository : IProviderRepository 
{ 
    private IRepository<IProvider> _genericProviderRepository; 

    //Explict public default constructor 
    public ProviderRepository(IRepository<IProvider> genericProviderRepository) 
    { 
     _genericProviderRepository = genericProviderRepository; 
    } 
} 

Répondre

2

Qu'est-ce que vous voulez faire est possible, mais vous devez dire l'unité comment carte des interfaces à des types de béton. AFAICT, votre configuration actuelle enregistre beaucoup de types, mais ne précise pas comment ils se rapportent les uns aux autres.

Ceci étant dit, static Service Locator is an anti-pattern. Envisagez de modifier votre code pour utiliser l'option Constructor Injection à la place. Cela permettrait également de simplifier considérablement votre code:

public class PrescriptionService 
{ 
    private readonly IProviderRepository pRepository; 

    public PrescriptionService(IProviderRepository pRepository) 
    { 
     if (pRepository == null) 
     { 
      throw new ArgumentNullException("pRepository"); 
     } 

     this.pRepository = pRepository; 
    } 
} 

Unity, vous seriez en mesure de câbler comme ceci:

var container = new UnityContainer(); 
container.RegisterType<PrescriptionService>(); 
container.RegisterType<IProviderRepository, ProviderRepository>(); 
container.RegisterType<IRepository<IProvider>, MyRepository<IProvider>>(); 

var ps = container.Resolve<PrescriptionService>(); 

Configurer le conteneur et resolve all components in the application's Composition Root.

Vous devez only use XML configuration if you need to be able to change certain components without recompiling your application.