我有一个基础存储库合同,其他合同可以扩展,如下所示
public interface IBaseRepository<T> where T : class
{
IList<T> GetContents();
}然后,还有其他一些合同对其进行了扩展,如下所示
public interface IRepository1 : IBaseRepository<MyClass1>
{
}
public interface IRepository2 : IBaseRepository<MyClass2>
{
}我按如下方式实现IRepository1
public class Repository1 : IRepository1
{
public IList<MyClass1> GetContents()
{
//some code goes here
}
} IRepository2也是如此
public class Repository2 : IRepository2
{
public IList<MyClass2> GetContents()
{
//some code goes here
}
} 现在我有了一个实现IService的服务Service1,如下所示
public class Service1 : IService
{
}我想在我的服务构造函数中使用我的基本存储库(IBaseRepository),获得这个基本存储库的一个实例,并像这样使用它
public class Service1 : IService
{
private IBaseRepository<T> _baseRepository;
public Service1(IBaseRepository<T> baseRepository)
{
_baseRepository = baseRepository;
}
public MyMethod1()
{
var contentsOfType1 = _baseRepository<MyClass1>.GetContents();
}
public MyMethod1()
{
var contentsOfType2 = _baseRepository<MyClass2>.GetContents();
}
}而这正是我无法做到的。
因此,我有一个带有类型T的通用基础存储库契约,还有一些扩展基础契约的其他契约(接口),还指定了T的类型。
所有这些契约(扩展泛型基础契约)都有各自的实现。
我想要做的是在我的服务类中,实例化这个泛型基础契约,并使用它来推断扩展类型(以及实现),并使用基础存储库中的方法。
因此,如果基础合约是IBaseRepository<T>
并且扩展合同是IRepository1 : IBaseRepository<MyClass1>
它由Repository1 : IRepository1实现
我想在我的服务类中使用它,比如
public class service()
{
*private IBaseRepository<T> _repo;
public service(IBaseRepository<T> repo)
{
*_repo = repo;
}
public void MyMethod()
{
*var x = _repo<MyClass1>.MethodFromIBaseRepository()
}
}所以这是我想要实现的*标记行,但我无法实现。
我在用城堡温莎做DI。
谢谢你们的帮助
发布于 2012-10-16 23:16:49
除了通用IRepository<T>之外,您不应该有其他存储库接口。如果您需要这些,那么您就缺少了一个抽象。
例如,人们拥有自定义存储库接口的一个常见原因是,他们有一个自定义查询,而另一些存储库则没有。例如:
public interface IEmployeeRepository : IRepository<Employee>
{
Employee GetEmployeeOfTheMonth(int month);
}这里的问题是IEmployeeRepository被滥用来进行“自定义查询”。自定义查询应该有自己的(通用)抽象:
// Defines a query
public interface IQuery<TResult>
{
}
// Defines the handler that will execute queries
public interface IQueryHandler<TQuery, TResult>
where TQuery : IQuery<TResult>
{
TResult Handle(TQuery query);
}有了这个抽象,我们可以向系统添加自定义查询,而不需要创建IRepository<T>派生:
public class GetEmployeeOfTheMonthQuery : IQuery<Employee>
{
[Range(1, 12)]
public int Month { get; set; }
}
class GetEmployeeOfTheMonthHandler : IQueryHandler<GetEmployeeOfTheMonthQuery, Employee>
{
public Employee Handle(GetEmployeeOfTheMonthQuery query)
{
// todo: query the database, web service, disk, what ever.
}
}需要知道当月雇员的消费者现在可以简单地依赖IQueryHandler<GetEmployeeOfTheMonthQuery, Employee>并执行查询,如下所示:
var query = new GetEmployeeOfTheMonthQuery { Month = 11 };
var employee = this.employeeOfMonthHandler.Handle(query);这可能看起来像是开销,但这种模型非常灵活、可伸缩,并具有许多有趣的好处。例如,很容易通过用装饰器包装处理程序来添加横切关注点。
这也允许我们的代码库隐藏在一个通用接口后面,这使得我们可以轻松地一次性批量注册它们,并向它们添加装饰器。
有关更深入的信息,请阅读本文:Meanwhile… on the query side of my architecture。
发布于 2012-10-16 13:34:33
不可能。控制反转容器通过构造函数提供依赖关系,因此它必须在构造函数中知道您想要获取什么类型。所以你应该这样做:
public class service()
{
private IBaseRepository<MyClass1> _repo;
public service(IBaseRepository<MyClass1> repo)
{
_repo = repo;
}
public void MyMethod()
{
var x = _repo.MethodFromIBaseRepository()
}
}https://stackoverflow.com/questions/12900078
复制相似问题