依赖注入和通用集合

时间:2009-11-06 09:17:02

标签: design-patterns generics collections dependency-injection

我正在试图通过使用具有多个IEnumerables的依赖注入来获得正确的模式。

我想从数据库中返回三种类型的对象:Projects,Batches和Tasks。我想创建一个具有以下形式的存储库:

public interface IRepository<T>
{
    IEnumerable<T> GetAll();
    IEnumerable<T> GetAllActive();
    IEnumerable<T> GetItemsByUserName(string UserName);
    T GetItemById(int ID);
}

因此,当我创建ProjectRepository的具体实现时,它将如下所示:

IEnumerable<Project> GetAll();
IEnumerable<Project> GetAllActive();
IEnumerable<Project> GetItemsByUserName(string UserName);
Project GetItemById(int ID);

类似于任务:

IEnumerable<Task> GetAll();
IEnumerable<Task> GetAllActive();
IEnumerable<Task> GetItemsByUserName(string UserName);
Task GetItemById(int ID);

我的困难在于尝试在我的调用代码中声明一个IRepository。当我声明引用时,我发现自己需要声明一个类型:

private IRepository<Project> Repository;

......这当然毫无意义。我在某个地方出错了,但此刻无法理解。如何使用依赖注入,以便我可以声明一个使用所有三种具体类型的接口?

希望我已经正确地解释了自己。

3 个答案:

答案 0 :(得分:5)

使用泛型:

public class YourClass<T>
{
    public YourClass(IRepository<T> repository)
    {
        var all = repository.GetAll();
    }
}

当然,在某些时候你需要提供T,这可能是这样的:

var projectClass = yourDIContainer.Resolve<YourClass<Project>>;

在使用DI容器注册类型方面,如果您的DI容器支持开放式泛型,则可能很有用。例如,请查看显示Unity如何支持此内容的this post

答案 1 :(得分:0)

希望这可能会帮助您制作代码。

public class Repository : IRepository<Repository>
{

    public Repository()
    {
    }

    #region IRepository<Repository> Members

    public IEnumerable<Repository> GetAll()
    {
        throw new Exception("The method or operation is not implemented.");
    }

    public IEnumerable<Repository> GetAllActive()
    {
        throw new Exception("The method or operation is not implemented.");
    }

    public IEnumerable<Repository> GetItemsByUserName(string UserName)
    {
        throw new Exception("The method or operation is not implemented.");
    }

    public Repository GetItemById(int ID)
    {
        throw new Exception("The method or operation is not implemented.");
    }

    #endregion
}



public class RepositoryCreator<T> where T : IRepository<T>
{
    public IRepository<Repository> getRepository()
    {
        Repository r = new Repository();
        return r;
    }


    public IRepository<Blah> getBlah()
    {
        Blah r = new Blah();
        return r;
    }
}

答案 2 :(得分:0)

鉴于您已将存储库接口定义为返回特定类型,为什么您认为提供您希望它在客户端代码中返回的类型毫无意义?

如果您不关心返回类型,那将毫无意义,但整个通用接口设计毫无意义。

如果您希望存储库对象仅使用指定的类型,那么您将需要三个对象(或者可能是一个具有三个接口的对象,具体取决于实现语言)来提供项目存储库,批处理存储库和任务存储库。 / p>

相关问题