简体   繁体   English

IRepository类型的C#方法参数 <BaseType> 不接受从BaseType继承的实现

[英]C# Method argument of Type IRepository<BaseType> doesnt accept implementation inheriting from BaseType

I have a generic service that performs the same actions against any given request/response combination. 我有一个通用服务,可以对任何给定的请求/响应组合执行相同的操作。 The only time anything specific happens is when it comes to persistence. 任何特定的事情唯一发生的时间就是持久性。 I'm trying to inject a specific implementation of an repository based off one of the Types (TRequest) in use. 我正在尝试根据使用中的一种类型(TRequest)注入存储库的特定实现。 So far I have the below, but Ninject and integration tests failing to find any repository that matches what its looking for, a Repository of Type EntityBase. 到目前为止,我有以下内容,但是Ninject和集成测试未能找到与其所需内容相匹配的任何存储库,即EntityBase类型的存储库。 I thought it would be fine as my specific entities inherit from EntityBase... 我认为这很好,因为我的特定实体继承自EntityBase ...

Error CS1503 Argument 1: cannot convert from 'Repositories.IRepository<Models.PersonModel>' to 'Repositories.IRepository<Models.EntityBase>' 错误CS1503参数1:无法从“ Repositories.IRepository <Models.PersonModel>”转换为“ Repositories.IRepository <Models.EntityBase>”

EDIT: I know why im getting the current error, its pretty explicit. 编辑:我知道为什么我得到当前的错误,它是相当明确的。 Any ideas how I can achieve this? 有什么想法可以实现这一目标吗?

PersonModel.cs PersonModel.cs

public class PersonModel : EntityBase
{
    blah blah
}

IRepository.cs IRepository.cs

public interface IRepository<T> 
{
    T Get(int id);
    void Add(T entity);
    void Delete(int id);
}

PersonRepository.cs PersonRepository.cs

public class PersonRepository : IRepository<PersonModel> 
{
    blah blah
}

Service.cs Service.cs

public class Service<TRequest, TResponse> : IService<TRequest, TResponse>
{
    private readonly IRepository<EntityBase> _repository;

    public Service(IRepository<EntityBase> repository)
    {
        _respository = repository
    }

    public TResponse Call(TRequest request)
    {
        var requestEntity = MapperFactory.GetMapperFor(typeof(TRequest)).Map(request); 

        _repository.Add(requestEntity)

        blah blah blah return            
    }
}

IoCModule.cs IoCModule.cs

Bind<IRepository<PersonModel>>().To<PersonRepository>();

This is because even though PersonModel inherits from EntityBase, this does not mean that IRepository<PersonModel> inherits from IRepository<EntityBase> . 这是因为即使PersonModel从EntityBase继承,也不意味着IRepository<PersonModel>IRepository<EntityBase>继承。

One possible way to deal with this is to have a third generic type: 解决此问题的一种可能方法是使用第三种泛型类型:

public class Service<TRequest, TResponse, T> : IService<TRequest, TResponse, T>
{
    private readonly IRepository<T> _repository;
}

Or another way is to specify the type of the service: 或者另一种方式是指定服务的类型:

public class PersonService<TRequest, TResponse> : IService<TRequest, TResponse>
{
    private readonly IRepository<PersonModel> _repository;
}

Because your IRepository< T > uses T as a parameter (input), you cannot make IRepository< T> covariant which would thus allow assigning IRepository< PersonModel> to IRepository< EntityBase>. 因为您的IRepository <T>使用T作为参数(输入),所以您无法使IRepository <T>协变量,从而允许将IRepository <PersonModel>分配给IRepository <EntityBase>。 So IoC cannot work here. 因此,IoC无法在这里工作。

You will need to write unit tests specific to each implementation for IRepository< T>, as opposed to relying on a generic test for IRepository< EntityBase>. 您将需要针对IRepository <T>的每个实现编写特定的单元测试,而不是依赖于IRepository <EntityBase>的通用测试。

因为Repositories.IRepository<Models.PersonModel>Repositories.IRepository<Models.EntityBase>实际上是不同的类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM