在我的项目中,我的所有存储库都有以下基类:
public abstract class RepositoryBase<TContext, TEntity> : Disposable, IRepository<TEntity>
where TEntity : class
where TContext : DbContext, new()
{...}
从基类继承的存储库未指定数据库上下文类型(因为上下文对于所有应用程序都不相同):
public class UserRepository<TContext> : RepositoryBase<TContext, User>
where TContext : BaseContext, new()
{
public UserRepository( IDatabaseFactory<TContext> databaseFactory, ILoggerFactory loggerFactory )
: base( databaseFactory, loggerFactory )
{...}
}
public class ProductRepository<TContext> : RepositoryBase<TContext, Product>
where TContext : BaseContext, new()
{...}
我知道 autofac 能够注册符合以下标准的所有类型:
builder.RegisterAssemblyTypes( assembly )
.Where(...)
.AsImplementedInterfaces();
有没有办法对从特定上下文的 RepositoryBase 继承的所有类型执行相同的操作?像这样:
public class MyContext : BaseContext { }
builder.RegisterAssemblyTypes( assembly )
.Where(...)
.AsImplementedInterfaces(/*specify MyContext as TContext*/);
TContext 是否以继承自 RepositoryBase 的类型而闻名?如果您知道UserRepository将使用MyContext,而ProductRepository将使用MyOtherContext,则可以这样定义它们,并让Autofac自动拾取它们:
public class UserRepository : RepositoryBase<MyContext, User>
{...}
public class ProductRepository : RepositoryBase<MyOtherContext, Product>
{...}
否则,我假设您有允许来自多个上下文的数据的要求?
public class MyContextUserRepository : RepositoryBase<MyContext, User>
{...}
public class MyOtherContextUserRepository : RepositoryBase<MyOtherContext, User>
{...}
在这种情况下,您可以按上述方式定义它们,但在解决时,您必须在该特定场景中传递所需的上下文
public class MyClass
{
readonly IRepository<User> _userRepository;
public MyClass(IRepository<User> userRepository)
{
_userRepository = userRepository;
}
}
var myClass = _container.Resolve<MyClass>(
new ResolvedParameter(
(x, y) => x.ParameterType == typeof (IRepository<User>),
(x, y) => y.Resolve<MyContextUserRepository>()));
或者,您可以在注册时执行此操作,在这种情况下,您可能会发现Autofac文档很有用。
评论后编辑
好的,您有多个应用程序共享一个包含接口、实现和实体的公共库。给定的应用程序可以定义其实现和实体,但只有一个特定于该应用程序的上下文。
// your application specific context
public class MySpecificApplicationContext : DbContext { }
// get your entity types that a given application uses
var entityTypes = GetEntityTypes();
// register a repository implementation for each entity type
// note RepositoryBase is not abstract for this example
for (var i = 0; i < entityTypes.Count; i++)
{
var entityType = entityTypes[i];
builder
.RegisterType(typeof (RepositoryBase<,>)
.MakeGenericType(typeof (MySpecificApplicationContext), entityType))
.As(typeof (IRepository<>).MakeGenericType(entityType))
.InstancePerLifetimeScope();
}
// resolve an entity repository
var userRepository = container.Resolve<IRepository<User>>();