Autofac约束绑定
本文关键字:绑定 约束 Autofac | 更新日期: 2023-09-27 18:27:25
我正在考虑从Ninject转移到Autofac,但很难转换其中一个有用的功能——通过属性进行约束绑定。
我目前有这个接口和实现:
public interface IRepository
{
IEnumerable<SomeObject> Get();
}
public class DBRepository : IRepository
{
public IEnumerable<SomeObject> Get()
{
// call the database
}
}
我有一个缓存的实现,它将检查缓存,如果没有发现任何内容,则调用数据库存储库。这被传递到构造函数:
[DataNeeded]
public class CacheRepository : IRepository
{
private readonly IRepository dataRepo;
public CacheRepository(IRepository dataRepo)
{
this.dataRepo = dataRepo;
}
public IEnumerable<SomeObject> Get()
{
// check the cache and if nothing found:
return this.dataRepo.Get();
}
}
最后,我有一个调用控制器,它将使用缓存来获取一个对象:
[CacheNeeded]
public class HomeController : ApiController
{
private readonly IRepository cacheRepo;
public CacheRepository(IRepository cacheRepo)
{
this.cacheRepo= cacheRepo;
}
public IEnumerable<SomeObject> Get()
{
return this.cacheRepo.Get();
}
}
正如您所看到的,我重用了这个接口,在数据存储库上添加了一个缓存层,这种模式工作起来非常巧妙。然后,我使用了一些自定义属性来告诉Ninject,我需要某种类型的IRepository。配置如下:
kernel.Bind<IRepository>().To<DbRepository>().WhenClassHas<DataNeeded>();
kernel.Bind<IRepository>().To<CacheRepository>().WhenClassHas<CacheNeeded>();
有没有办法在Autofac中模仿这种行为?
我想不出用Autofac来实现这种机制的任何简洁明了的方法,但也许你可以利用Autofac选择实现的含义之一。我会使用键控服务,在您的情况下是这样的:首先,您需要定义一个枚举,而不是自定义属性
enum RepositoryKind {CacheNeeded, DataNeeded}
然后注册组件,用那些提供缓存或数据功能的组件来标记它们,例如:
builder.RegisterType<DbRepository>()
.Keyed<IRepository>(RepositoryKind.CacheNeeded);
builder.Register(c => new CacheRepository(c.ResolveKeyed<IRepository(RepositoryKind.CacheNeeded)))
.Keyed<IRepository>(RepositoryKind.DataNeeded);
builder.Register(c => new HomeController(c.ResolveKeyed<IRepository>(RepositoryKind.DataNeeded)));
这种方法的优点是,您不会在控制器中透露实现细节,也不会在配置中应用缓存。