2

我有一個應用程序借用了John Papa Code Camper應用程序中的大量代碼。在他的應用程序中,他使用Repository工廠來提供新的存儲庫或現有存儲庫(如果已存在於緩存中)。對我來說,這似乎過於複雜,我想知道如果我可以使用Unity來做同樣的事情。下面是我目前使用的代碼示例:從存儲庫工廠轉換爲EF的IOC解決方案?

在UOW他有這個代碼來獲取回購:

public IRepository<Answer> Answers { get { return GetStandardRepo<Answer>(); } } 

此代碼來調用庫提供商:

protected IRepositoryProvider RepositoryProvider { get; set; } 

    protected IRepository<T> GetStandardRepo<T>() where T : class 
    { 
     return RepositoryProvider.GetRepositoryForEntityType<T>(); 
    } 
    protected T GetRepo<T>() where T : class 
    { 
     return RepositoryProvider.GetRepository<T>(); 
    } 

以下版本庫提供者:

public class RepositoryProvider : IRepositoryProvider 
{ 
    public RepositoryProvider(RepositoryFactories repositoryFactories) 
    { 
     _repositoryFactories = repositoryFactories; 
     Repositories = new Dictionary<Type, object>(); 
    } 

    //public RepositoryProvider(RepositoryFactories repositoryFactories) 
    //{ 
    // _repositoryFactories = repositoryFactories; 
    // Repositories = new Dictionary<Type, object>(); 
    //} 

    /// <summary> 
    /// Get and set the <see cref="DbContext"/> with which to initialize a repository 
    /// if one must be created. 
    /// </summary> 
    public DbContext DbContext { get; set; } 

    /// <summary> 
    /// Get or create-and-cache the default <see cref="IRepository{T}"/> for an entity of type T. 
    /// </summary> 
    /// <typeparam name="T"> 
    /// Root entity type of the <see cref="IRepository{T}"/>. 
    /// </typeparam> 
    /// <remarks> 
    /// If can't find repository in cache, use a factory to create one. 
    /// </remarks> 
    public IRepository<T> GetRepositoryForEntityType<T>() where T : class 
    { 
     return GetRepository<IRepository<T>>(
      _repositoryFactories.GetRepositoryFactoryForEntityType<T>()); 
    } 

    /// <summary> 
    /// Get or create-and-cache a repository of type T. 
    /// </summary> 
    /// <typeparam name="T"> 
    /// Type of the repository, typically a custom repository interface. 
    /// </typeparam> 
    /// <param name="factory"> 
    /// An optional repository creation function that takes a DbContext argument 
    /// and returns a repository of T. Used if the repository must be created and 
    /// caller wants to specify the specific factory to use rather than one 
    /// of the injected <see cref="RepositoryFactories"/>. 
    /// </param> 
    /// <remarks> 
    /// Looks for the requested repository in its cache, returning if found. 
    /// If not found, tries to make one using <see cref="MakeRepository{T}"/>. 
    /// </remarks> 
    public virtual T GetRepository<T>(Func<DbContext, object> factory = null) where T : class 
    { 
     // Look for T dictionary cache under typeof(T). 
     object repoObj; 
     Repositories.TryGetValue(typeof(T), out repoObj); 
     if (repoObj != null) 
     { 
      return (T)repoObj; 
     } 

     // Not found or null; make one, add to dictionary cache, and return it. 
     return MakeRepository<T>(factory, DbContext); 
    } 

    /// <summary> 
    /// Get the dictionary of repository objects, keyed by repository type. 
    /// </summary> 
    /// <remarks> 
    /// Caller must know how to cast the repository object to a useful type. 
    /// <p>This is an extension point. You can register fully made repositories here 
    /// and they will be used instead of the ones this provider would otherwise create.</p> 
    /// </remarks> 
    protected Dictionary<Type, object> Repositories { get; private set; } 

    /// <summary>Make a repository of type T.</summary> 
    /// <typeparam name="T">Type of repository to make.</typeparam> 
    /// <param name="dbContext"> 
    /// The <see cref="DbContext"/> with which to initialize the repository. 
    /// </param>   
    /// <param name="factory"> 
    /// Factory with <see cref="DbContext"/> argument. Used to make the repository. 
    /// If null, gets factory from <see cref="_repositoryFactories"/>. 
    /// </param> 
    /// <returns></returns> 
    protected virtual T MakeRepository<T>(Func<DbContext, object> factory, DbContext dbContext) 
    { 
     var f = factory ?? _repositoryFactories.GetRepositoryFactory<T>(); 
     if (f == null) 
     { 
      throw new NotImplementedException("No factory for repository type, " + typeof(T).FullName); 
     } 
     var repo = (T)f(dbContext); 
     Repositories[typeof(T)] = repo; 
     return repo; 
    } 

    /// <summary> 
    /// Set the repository for type T that this provider should return. 
    /// </summary> 
    /// <remarks> 
    /// Plug in a custom repository if you don't want this provider to create one. 
    /// Useful in testing and when developing without a backend 
    /// implementation of the object returned by a repository of type T. 
    /// </remarks> 
    public void SetRepository<T>(T repository) 
    { 
     Repositories[typeof(T)] = repository; 
    } 

    /// <summary> 
    /// The <see cref="RepositoryFactories"/> with which to create a new repository. 
    /// </summary> 
    /// <remarks> 
    /// Should be initialized by constructor injection 
    /// </remarks> 
    private RepositoryFactories _repositoryFactories; 

} 

這是我可以使用Unity的東西,如果s o有人可以給我一些關於如何在Unity中創建存儲庫的提示,以便他們可以共享。請注意,我有兩種類型的存儲庫。泛型和自定義。現在這些使用GetStandardRepo和GetRepo返回。如果可能的話,我想要映射,以確定哪些回購我得到我的Unity配置文件,以便它清晰可見。

這裏是統一配置我到目前爲止:

 container.RegisterType<RepositoryFactories>(new ContainerControlledLifetimeManager()); 
     container.RegisterType<IRepositoryProvider, RepositoryProvider>(); 
     container.RegisterType<IUow, Uow>(); 
     container.RegisterType<Contracts.Services.IContentService, Services.ContentService>(); 
     container.RegisterType<IAnswerService, AnswerService>(); 

回答

0

團結支持MVC項目註冊組件「每請求」。第一次從容器提供特定的存儲庫時,它將被實例化。在同一個HTTP請求期間對該存儲庫的任何後續請求都將使用該存儲庫,而不是創建一個新存儲庫。

你可以閱讀更多關於如何使用下面的鏈接工作。基本上,你希望將對象的生命週期範圍控制爲單例,而不是每個依賴。

Unity Documentation on MSDN