CastleWindsor,通用存储库和两个数据库上下文

用户名

我有两个单独的数据库,用于存储文档和用户。我还实现了通用存储库模式:

 public class Repository<T> : IRepository<T> where T : class
    {
        public DbContext Context { get; set; }

        public Repository()
        {

        }

        public IEnumerable<T> Get(Expression<Func<T, bool>> expression)
        {
            return Context.Set<T>().Where(expression).AsEnumerable();
        }

        public void Add(T entity)
        {
            Context.Set<T>().Add(entity);
        }

        public void Delete(T entity)
        {
            Context.Set<T>().Remove(entity);
        }

        public void Update(T entity)
        {
            Context.Set<T>().Attach(entity);
            Context.Entry<T>(entity).State = EntityState.Modified;
        }


        public void SaveChanges()
        {
            Context.SaveChanges();
        }
    }

问题是实体存储在不同的DbContext中,我不能使用类似这样的东西:

container.Register(Component.For(typeof(IRepository<>)).ImplementedBy(typeof(Repository<>));

如何指定每个实体应使用哪个DbContext?
例如,如果要创建存储库,则意味着应该使用一个数据库,但是如果要存储库,则应该使用另一个上下文。或者我应该创建两个仓库类,如下所示:

public class AttachmetRepository<T> : IRepository<T> where T : class
    {
        public AttachmetsDbContext Context { get; set; }
        ...
    }

    public class UserRepository<T> : IRepository<T> where T : class
    {
        public UsersDbContext Context { get; set; }
        ...
    }

我不想使用两个不同的存储库的原因是为了保持服务简单,例如:

 public class SomeService: ISomeService
    {
        public IRepository<User> UserRepository { get; set; } //database 1
        public IRepository<Comment> CommentsRepository { get; set; } //database 1
        public IRepository<Attachment> AttachmentRepository { get; set; } //database 2
        ...
}

UPD:正如Ognyan所建议的那样,我使用了FactoryMethod,这有所帮助!非常感谢,Ognyan!我是CastleWindsor的新手,我不确定它是最好,最快的方法,但这是我的代码:

public class EFDatabaseInstaller : IWindsorInstaller
    {
        public void Install(IWindsorContainer container, IConfigurationStore store)
        {
            container.Register(Component.For<AttContext>().LifeStyle.PerWebRequest);
            container.Register(Component.For<DefContext>().LifeStyle.PerWebRequest);

            container.Register(Component.For(typeof(IRepository<>)).UsingFactoryMethod((kernel, context) =>
            {
                var genericType = context.RequestedType.GetGenericArguments()[0];

                Type type = typeof(Repository<>).MakeGenericType(genericType);
                object repository = Activator.CreateInstance(type);
                PropertyInfo dbContextProperty = type.GetProperty("Context");

                if (genericType == typeof(Attachment))
                {
                    dbContextProperty.SetValue(repository, kernel.Resolve<AttContext>());
                }
                else
                {
                    dbContextProperty.SetValue(repository, kernel.Resolve<DefContext>());
                }

                return repository;
            }).LifeStyle.PerWebRequest);
        }
    }
奥格扬·迪米特洛夫(Ognyan Dimitrov)

首先,您无需在存储库中对DbContext进行硬编码。您可以像这样重新构建存储库:

public class Repository<T> : IRepository<T> where T : class
{
    private readonly DbContext _dbContext;
    // you can even make it IDbContextProvider with .Current() method in order not
    // to place a hard dependency but depend on Interface which is the proper way.
    // I was in a hurry and did not want to overcomplicate the implementation.

    public Repository(DbContext dbContext)
    {
        _dbContext = dbContext;
    }

    protected IDbSet<T> CreateSet<T>() where T : class
    {
        return _dbContext.Set<T>(); 
    }

    public virtual T Find(int id)
    {
        return CreateSet<T>().Find(id);
    }
... 
}

之后,您需要一种工厂方法和一种区分目标数据库的方法。区分的一种方法是从factory方法的CreationContext获取信息:

private static DbContext DbContextFactoryMethod(IKernel k, ComponentModel cm, CreationContext c)

在这里,您可以遍历分辨率堆栈,查看它是否是包含IRepository或其他实体的图形的一部分,并选择您的数据库。

这样,您将在存储库中获得适当的DbContext,而不会将所有DbContext保留在其中,随着时间的推移,它们将变得越来越麻烦。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

实体框架:两个不同的上下文和一个数据库

来自分类Dev

TransactionScope下的两个数据库上下文失败

来自分类Dev

具有通用数据库上下文的存储库模式

来自分类Dev

使用存储库模式时的多个数据库上下文

来自分类Dev

使用ToList()和.AsQueryable()连接两个不同的数据库上下文有什么区别?

来自分类Dev

哪个是将存储库模式用于数据库上下文的最佳代码?

来自分类Dev

在ASP.Net MVC中合并多个数据库上下文

来自分类Dev

如何在asp范围内修复多个数据库上下文

来自分类Dev

无法在数据库msbotframework nodejs中存储上下文对象

来自分类Dev

两个数据库的模糊和精确匹配

来自分类Dev

在EF数据库上下文中两次使用相同的c#模型

来自分类Dev

在EF数据库上下文中两次使用相同的c#模型

来自分类Dev

Light在MVC中注入数据库上下文

来自分类Dev

静态数据库上下文混乱

来自分类Dev

Glass上下文数据库null

来自分类Dev

Linq Sql数据库上下文丢失方法

来自分类Dev

使用不同的上下文访问数据库

来自分类Dev

数据库上下文中缺少GetTable <TEntity>()

来自分类Dev

Glass上下文数据库null

来自分类Dev

为什么我的数据库上下文被处置

来自分类Dev

SignalR 和数据库上下文处理

来自分类Dev

使用UnitOfWork模拟上下文和存储库

来自分类Dev

两个数据库的同步

来自分类Dev

实体框架多上下文和Microsoft Azure。如何更新数据库?

来自分类Dev

C#以更好的方式使用数据库上下文和异常处理(DRY)

来自分类Dev

从Entity Framework Core中的cookie和基本路径创建数据库上下文

来自分类Dev

ASP.NET MVC4设置数据库上下文和模型

来自分类Dev

C#以更好的方式使用数据库上下文和异常处理(DRY)

来自分类Dev

如何在共享同一数据库的两个不同应用程序之间同步持久性上下文?

Related 相关文章

  1. 1

    实体框架:两个不同的上下文和一个数据库

  2. 2

    TransactionScope下的两个数据库上下文失败

  3. 3

    具有通用数据库上下文的存储库模式

  4. 4

    使用存储库模式时的多个数据库上下文

  5. 5

    使用ToList()和.AsQueryable()连接两个不同的数据库上下文有什么区别?

  6. 6

    哪个是将存储库模式用于数据库上下文的最佳代码?

  7. 7

    在ASP.Net MVC中合并多个数据库上下文

  8. 8

    如何在asp范围内修复多个数据库上下文

  9. 9

    无法在数据库msbotframework nodejs中存储上下文对象

  10. 10

    两个数据库的模糊和精确匹配

  11. 11

    在EF数据库上下文中两次使用相同的c#模型

  12. 12

    在EF数据库上下文中两次使用相同的c#模型

  13. 13

    Light在MVC中注入数据库上下文

  14. 14

    静态数据库上下文混乱

  15. 15

    Glass上下文数据库null

  16. 16

    Linq Sql数据库上下文丢失方法

  17. 17

    使用不同的上下文访问数据库

  18. 18

    数据库上下文中缺少GetTable <TEntity>()

  19. 19

    Glass上下文数据库null

  20. 20

    为什么我的数据库上下文被处置

  21. 21

    SignalR 和数据库上下文处理

  22. 22

    使用UnitOfWork模拟上下文和存储库

  23. 23

    两个数据库的同步

  24. 24

    实体框架多上下文和Microsoft Azure。如何更新数据库?

  25. 25

    C#以更好的方式使用数据库上下文和异常处理(DRY)

  26. 26

    从Entity Framework Core中的cookie和基本路径创建数据库上下文

  27. 27

    ASP.NET MVC4设置数据库上下文和模型

  28. 28

    C#以更好的方式使用数据库上下文和异常处理(DRY)

  29. 29

    如何在共享同一数据库的两个不同应用程序之间同步持久性上下文?

热门标签

归档