簡體   English   中英

C#/ EF和存儲庫模式:將ObjectContext放在具有多個存儲庫的解決方案中的位置?

[英]C#/EF and the Repository Pattern: Where to put the ObjectContext in a solution with multiple repositories?

我的應用程序中有多個存儲庫。 我應該把ObjectContext放在哪里? 現在,我有一個像ObjectContext ctx;的引用ObjectContext ctx; 在每個存儲庫中。 什么是最聰明,最安全的方法?

只有在Repository方法提交事務時,才能接受具有多個ObjectContext實例的設計。 否則,提交事務的外部調用可能無法保留您想要的所有內容,因為您將保留對ObjectContext不同實例的引用。

如果要將ObjectContext限制為單個實例,則可以構建包含ObjectContextRepositoryProvider類,並管理存儲庫操作到數據提交的傳播。 這可以通過以下方式實現: - 將ObjectContext引用注入每個存儲庫,或者 - 將存儲庫事件訂閱到調用ObjectContext上相應方法的EventHandler

以下是我使用的高度可插拔的實現:

存儲庫提供程序接口

public interface IRepositoryProvider
{
    IRepository this[Type repositoryType] { get; }
}

存儲庫工廠接口

該實現依賴於IEnumerable<IFilteredRepositoryFactory>

public interface IFilteredRepositoryFactory{
   bool CanCreateRepository(Type repositoryType);
   IRepository CreateRepository(Type repositoryType, ObjectContext context);
}

所以,實現看起來像:

存儲庫提供程序類

public class RepositoryProvider
{
    public RepositoryProvider(ObjectContext context, IEnumerable<IFilteredRepositoryFactory> repositoryFactories)
    {
        _context = context;
        _repositoryFactories = repositoryFactories;
    }

    private readonly ObjectContext _context;
    private readonly IEnumerable<IFilteredRepositoryFactory> _repositoryFactories;
    private readonly Dictionary<Type, IRepository> _loadedRepositories;

    IRepository this[Type repositoryType]
    {
        get
        {
            if(_loadedRepositories.ContainsKey(repositoryType))
            {
                return _loadedRepositories[repositoryType];
            }
            var repository = GetFactory(repositoryType).CreateRepository(repositoryType, _context);
            _loadedRepositories.Add(repositoryType,repository);
            return repository;
        }
    }

    IFilteredRepositoryFactory GetFactory(Type repositoryType)
    {
        //throws an exception if no repository factory is found
        return _repositoryFactories.First(x => x.CanCreateRepository(repositoryType));
    }
}

應該注意的是,第一個匹配的工廠實現將創建一個新的Repository 因此,如果工廠集合包含多個可以為給定存儲庫Type創建Repository工廠,則將使用可枚舉中的第一個IFilteredRepositoryFactory對象,並且將忽略任何后續工廠。 另外,如果沒有注冊工廠,則會拋出異常。

我通常做的是創建一個ObjectContext並將其存儲在線程本地存儲中(使用NamedThreadDataSlot)並從那里訪問ObjectContext。 這確保了ObjectContext在請求中共享,該請求將由一個線程處理。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM