2011-12-20 2 views
4

IoC 컨테이너로 Autofac을 사용하고 있습니다. 내가 가지고 :개방형 제네릭 유형, 폐쇄 형 제네릭 유형을 등록하고 autofac을 사용하여 둘 다 장식하는 방법은 무엇입니까?

  1. IRepository<> 내 저장소 인터페이스;
  2. DbContextRepository<>, EntityFramework의 DbContext를 사용하는 저장소의 일반적인 구현.
  3. 어셈블리 내에 닫힌 유형의 리포지토리 중 일부는 말하면 PersonRepository : DbContextRepository<Person>입니다.
  4. RepositoryDecorator<>, 내 저장소를 몇 가지 표준 추가 동작으로 장식합니다.
  5. 내가 이런 식으로 그들 모두를 등록 autofac을 사용하고

:

builder.RegisterGeneric(typeof(DbContextRepository<>)) 
      .Named("repo", typeof(IRepository<>)); 

builder.RegisterGenericDecorator(
       typeof(RepositoryDecorator<>), 
       typeof(IRepository<>), 
       fromKey: "repo");    

var repositorios = Assembly.GetAssembly(typeof(PersonRepository)); 
builder.RegisterAssemblyTypes(repositorios).Where(t => t.Name.EndsWith("Repository")) 
      .AsClosedTypesOf(typeof(IRepository<>)) 
      .Named("repo2", typeof(IRepository<>)) 
      .PropertiesAutowired(); 

builder.RegisterGenericDecorator(
       typeof(RepositoryDecorator<>), 
       typeof(IRepository<>), 
       fromKey: "repo2"); 

내가 뭘하려고 오전입니다 :

  1. IRepository<>의 일반적인 구현으로 DbContextRepository<>을 등록;
  2. 폐쇄 형 저장소를 등록하면 필요할 때 이전 등록에 과부하가 걸릴 수 있습니다.
  3. 그런 다음 컨테이너를 IRepository를 해결하도록 요청할 때 컨테이너를 요청하면 IRepository를 올바르게 구현 한 RepositoryDecorator가 DbContextRepository 또는 이미 등록 된 닫힌 형식이됩니다.

닫힌 형식 구현이없는 IRepository<Product>을 해결하려고하면 Decorated DbContextRepository가 올바르게 반환됩니다. 내가 폐쇄 형 구현이있는 , IRepository<Person>를 해결하려고 할 때

는하지만, 그것은 또한 나에게 대신 장식 PersonRepository의 장식 DbContextRepository을 제공합니다.

+0

문제를 재현하려고합니다. 코드를 더 많이 제공 할 수 있습니까? 콘크리트 장식자가 도움이 될 수 있습니까? RepositorioVisibilidade는 RepositoryDecorator가 될 예정입니까? –

+0

고마워. – rcaval

+0

일부 유닛 테스트를하고 Autofac에 확장 기능을 제공하려고합니다. @ default.kramer와 같은 크레디트,'.AsNamedClosedTypesOf (...) '와 같은 것 – rcaval

답변

6

문제는 Named("repo2", typeof(IRepository<>))이 (가) 당신이 생각하는대로하지 않는 것입니다. 검사중인 유형에 대해 유형을 명시 적으로 지정해야합니다.

static Type GetIRepositoryType(Type type) 
{ 
    return type.GetInterfaces() 
     .Where(i => i.IsGenericType 
      && i.GetGenericTypeDefinition() == typeof(IRepository<>)) 
     .Single(); 
} 

builder.RegisterAssemblyTypes(this.GetType().Assembly) 
    .Where(t => t.IsClosedTypeOf(typeof(DbContextRepository<>))) 
    .As(t => new Autofac.Core.KeyedService("repo2", GetIRepositoryType(t))) 
    .PropertiesAutowired(); 
+0

괜찮습니다. 내가 찾고 있었던 것은 .AsClosedTypesOf (typeof (IRepository <>), withName : "repo")와 같은 것이 었습니다. 존재하지도 않고 단지 당신이 한 일입니다. – rcaval

+0

좋은 답변입니다. 이는 API에서 특별히 발견 할 수 없기 때문에 까다로운 내용이었습니다. –

+0

감사합니다. 실제로 발견 할 수는 없지만, 매우 좋았습니다. 잘못 입력하지 마십시오. 문서는 일반 등록에 대한 일반 장식의 예제만을 보여줍니다. –

관련 문제