如何使用Autofac注册开放泛型接口实现类及普通接口多实现类
嗨,这个问题我熟!Autofac处理这两种注册场景其实挺顺手的,我给你拆解成两部分讲,附代码示例,一看就懂:
假设你有一个普通接口(比如IOrderProcessor),还有一堆实现类(比如OnlineOrderProcessor、OfflineOrderProcessor),注册方式分两种:
逐个手动注册:适合实现类不多的情况,直接给每个实现类绑定接口:
var builder = new ContainerBuilder(); builder.RegisterType<OnlineOrderProcessor>().As<IOrderProcessor>(); builder.RegisterType<OfflineOrderProcessor>().As<IOrderProcessor>(); // 有多少个实现就加多少行 var container = builder.Build();解析的时候,只要注入
IEnumerable<IOrderProcessor>就能拿到所有实现,或者用容器直接解析:var allProcessors = container.Resolve<IEnumerable<IOrderProcessor>>();批量扫描注册:如果实现类都在同一个程序集里,用扫描方式更高效,不用逐个写:
builder.RegisterAssemblyTypes(typeof(IOrderProcessor).Assembly) .Where(t => typeof(IOrderProcessor).IsAssignableFrom(t) && !t.IsInterface) .As<IOrderProcessor>();这段代码会自动扫描
IOrderProcessor所在程序集里所有实现了该接口的非接口类,一次性完成注册。
比如你有开放泛型接口IRepository<T>,还有直接实现它的类(比如GenericRepository<T>、CachedRepository<T>),注册方式也分两种:
单个开放泛型注册:直接绑定开放泛型类型:
builder.RegisterGeneric(typeof(GenericRepository<>)).As(typeof(IRepository<>)); builder.RegisterGeneric(typeof(CachedRepository<>)).As(typeof(IRepository<>));当你需要解析封闭泛型(比如
IRepository<Product>)时,Autofac会自动匹配对应的开放泛型实现,注入IEnumerable<IRepository<Product>>就能拿到所有对应封闭泛型的实现。批量扫描开放泛型实现:如果程序集里有多个开放泛型实现类,可以用
AsClosedTypesOf自动注册:builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()) .AsClosedTypesOf(typeof(IRepository<>));这个方法会自动识别程序集中所有实现了
IRepository<>的开放泛型类,并把它们注册为对应的封闭泛型接口。
小提示
如果有多个同类型的实现(不管是普通接口还是泛型接口),想指定某一个解析,可以用命名注册:
// 普通接口命名注册 builder.RegisterType<OnlineOrderProcessor>().Named<IOrderProcessor>("online"); // 泛型接口命名注册 builder.RegisterGeneric(typeof(CachedRepository<>)).Named<IRepository<>>("cached"); // 解析时指定名称 var onlineProcessor = container.ResolveNamed<IOrderProcessor>("online"); var cachedProductRepo = container.ResolveNamed<IRepository<Product>>("cached");
这样两种场景就都覆盖到了,你可以根据自己的项目结构选合适的注册方式~
内容的提问来源于stack exchange,提问作者Aleksandr Neizvestnyi

