[英]How do I inject a repository into a custom MembershipProvider using AutoFac
[英]How to inject dynamic DbContext object into repository using Autofac
我有一个.net核心Web API应用程序,其中我在使用带有服务层,工作单元和存储库层模式的实体框架核心。 对于DI,我正在使用Autofac。
该应用程序有多个客户端 , 每个客户端都有自己的数据库 ,所有这些数据库的架构都是相同的。 通过每个API调用,我将获得客户端特定的连接字符串,必须使用该字符串创建DbContext并将其用于所有操作。
在启动类中,我已经注册了dbcontext ClientDbContext和所有其他类。 调用工作单元类时,我将基于连接字符串创建新的DbContext。 我希望存储库使用此实例, 但是存储库仍使用在启动时创建的初始ClientDbContext实例 。
如何使存储库使用新的DbContext实例?
工作单位:
public class UnitOfWork : IUnitOfWork
{
public ClientDbContext ClientDbContext { get; private set; }
public UnitOfWork ()
{
}
public void SetDbContext(string connectionString)
{
if(ClientDbContext == null)
{
//creating new db context instance here
ClientDbContext = MembershipRepository.CreateDbContext(connectionString);
}
}
//property injection
public IGenericRepository<SomeEntity, ClientDbContext> SomeEntityGenericRepository { get; }
}
通用存储库:
public class GenericRepository<TEntity, TDbContext> : IGenericRepository<TEntity, TDbContext> where TEntity : class
where TDbContext : DbContext
{
private readonly TDbContext _context;
private readonly DbSet<TEntity> _dbset;
public GenericRepository(TDbContext context)
{
// need to get updated context here, but getting the initial one
_context = context;
_dbset = _context.Set<TEntity>();
}
}
在Startup.cs中调用的Autofac模块:
builder.Register(a => new ClientDbContext()).InstancePerLifetimeScope();
builder.RegisterGeneric(typeof(GenericRepository<,>)).As(typeof(IGenericRepository<,>)).InstancePerLifetimeScope();
//Register Unit of Work here
builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().InstancePerLifetimeScope().PropertiesAutowired();
//Register Services here
builder.RegisterType<SomeService>().As<ISomeService>().InstancePerLifetimeScope();
谁能帮我解决上述要求?
有什么方法可以使Autofac使用新创建的dbcontext对象?
代替
builder.Register(a => new ClientDbContext()).InstancePerLifetimeScope();
你可以用
builder.Register(c => c.Resolve<IUnitOfWork>().ClientDbContext)
.InstancePerLifetimeScope();
顺便说一下,我不确定IUnitOfWork
的责任是IUnitOfWork
。 实现此目的的另一种方法是拥有一个类,该类将提供有关当前用户的信息:
public interface IClientContext
{
public String ClientIdentifier { get; }
}
然后, DbContextFactory
,将创建DbContext
基础上, IClientContext
public interface IDbContextFactory
{
IDbContext CreateDbContext();
}
public class DbContextFactory
{
public DbContextFactory(IClientContext clientContext)
{
this._clientContext = clientContext;
}
private readonly IClientContext _clientContext;
public IDbContext CreateDbContext()
{
// get the connectionstring from IClientContext and return the IDbContext
}
}
IClientContext
的具体实现取决于您获取此信息的方式,它可以从当前的HttpContext
或由您决定的任何其他方式。 看来,在某些时候你叫SetDbContext
你可以通过创建一个保持这样XXXClientContextProvider
其中XXX
是相对于你得到这个信息的方式。
public class XXXClientContextProvider
{
private IClientContext _clientContext;
public IClientContext GetClientContext()
{
if(this._clientContext == null)
{
throw new Exception("client context is null. You should do X or Y");
}
return this._clientContext;
}
public void SetClientContext(String clientId)
{
if(this._clientContext != null)
{
throw new Exception("client context has already been set");
}
this._clientContext = new StaticClientContext(clientId);
}
}
然后像这样注册所有内容:
builder.Register(c => c.Resolve<IClientContextProvider>().GetClientContext())
.As<IClientContext>()
.InstancePerLifetime();
builder.Register(c => c.Resolve<IDbContextFactory>().CreateDbContext())
.As<IDbContext>()
.InstancePerLifetime();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.