rca*_*val 4 c# inversion-of-control autofac
我使用Autofac作为我的IoC容器.我有:
IRepository<>,我的存储库界面;DbContextRepository<>,使用EntityFramework的DbContext的存储库的通用实现; PersonRepository : DbContextRepository<Person>,程序集中的一些封闭类型的存储库 ;RepositoryDecorator<>,用一些标准的额外行为来装饰我的存储库;我正在使用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");
Run Code Online (Sandbox Code Playgroud)
我想要做的是:
DbContextRepository<>为通用实施IRepository<>; 当我尝试解析一个IRepository<Product>没有闭合类型实现的时,它会正确返回一个装饰的DbContextRepository.
但是,当我尝试解决的IRepository<Person>,它有一个封闭式的实现,这也给了我一个装饰DbContextRepository,而不是装饰PersonRepository.
问题是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();
Run Code Online (Sandbox Code Playgroud)