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