1

我有以下。

public interface IMyService<T>
   where T: BaseModelType
{
    Process(T input);
}        

public class BaseModelType
{
  ...some property
}

public class SomeClass : BaseModelType
{
   ...some properties
}

public ServiceImpl : IMyService<SomeClass>
{
    ...the properties
}

然后我有一个统一容器,我在其中注册了通用接口的所有实现。我希望能够使用 unitycontainer 的 resolve 方法来获取接口,然后对其进行一些工作。当我想使用 Resolve 方法时,我在运行时有类型

 new UnityContainer.Resolve(myTypeVar)

我能以某种方式把它变成

 IMyService<BaseModelType> value = new UnityContainer.Resolve(myTypeVar) //want to cast it here from object.

这样我就可以调用接口定义的 Process 方法。

4

1 回答 1

3

不,因为IMyService<SomeClass>没有实现IMyService<BaseModelType>. 如果你看一下 Process 方法的实现:

public void Process(SomeClass input){...}

这显然假设你给它一个SomeClass. 它应该能够安全地访问SomeClass. 但是如果你用 aBaseModelType作为参数调用这个方法,那是行不通的,不是吗?

假设您在运行时知道您的参数input将是给定通用IMyService<T>接口的正确类型,您有两个选择:

  1. 通过反射调用通用方法签名。有点慢,但很有效。
  2. 为 添加一个非通用父接口IMyService,它需要一个BaseModelType. 在您的服务实现中,您可以通过将输入转换为该实现的预期类型来实现此方法。这需要更多代码。但是您可以通过拥有一个实现此方法的通用抽象基类来缓解这种情况,这样其他实现就不必这样做了。

    void Main()
    {
        var s = (IMyService)new ServiceImpl();
        s.Process(new SomeClass());
    }
    
    public interface IMyService
    {
        void Process(BaseModelType input);
    }
    
    public interface IMyService<in T> : IMyService
       where T: BaseModelType
    {
        void Process(T input);
    }
    
    public class BaseModelType{}
    
    public class SomeClass : BaseModelType{}
    
    public abstract class ServiceBase<T> : IMyService<T>
        where T: BaseModelType
    {
         void IMyService.Process(BaseModelType input)
         {
             Process((T)input);
         }
    
         public abstract void Process(T input);
    }
    
    public class ServiceImpl : ServiceBase<SomeClass>{
        public override void Process(SomeClass input){}
    }
    
于 2012-12-13T15:58:38.617 回答