C#接口实现:做正确的事情

时间:2010-10-18 09:30:16

标签: c# .net inheritance interface

我有一个假设的经销商可以提供一些服务;所有服务都是相同的:它们威胁一些IRequest数据,加上一些IExtraData,并提供IResponse。

请阅读此代码(使用C#2.0):

    public interface IResellerService<in TIn, in TInExtra, out TOut, in TOutExtra>
    where TIn : IRequest
    where TInExtra : IExtraData
    where TOut : IResponse
    where TOutExtra : IExtraData
{
    #region Properties
    string Code
    {
        get;
        set;
    } 

    //Some other simple properties here...
    #endregion

    //Some methods there...
}

//Need a collection of IResellerServices; using a IList just to have Add facility
public interface IResellerServices : IList<IResellerService<IRequest, IExtraData, IResponse, IExtraData>>
{
    IResellerService<IRequest, IExtraData, IResponse, IExtraData> Get(string code);
    void Update(IResellerService<IRequest, IExtraData, IResponse, IExtraData> reseller);
    void Delete(string code);
    void Disable(string code);
}

public class AvailabilityService : IResellerService<AvailabilityDocumentRequest, AvailabilityInputExtraData, AvailabilityDocumentResponse, AvailabilityOutputExtraData>
{
    //Here the interface implementation;


    /* 
     NOTE IResellerService declaration
     AvailabilityDocumentRequest : IRequest
     AvailabilityInputExtraData : IExtraData
     AvailabilityDocumentResponse : IResponse
     AvailabilityOutputExtraData : IExtraData
     */
}


[Serializable]
public class Reseller : IReseller
{
    #region Properties
    public string Code
    {
        get;
        set;
    }

    [XmlArray("Services")]
    [XmlArrayItem("Service")]
    public IResellerServices Services
    { get; set; }

    //Some other simple properties here...
    #endregion

    //Some methods there...
}

//Just to make me explain...
void Main()
{
    Reseller res = new Reseller;
    //Fill reseller properties here...
    //...

    AvailabilityService service = new AvailabilityService();
    //Fill service properties here...
    //...

    //ERROR!
    res.Add(service); //<-- ERROR! Need to cast my AvailabilityService to IResellerService<IRequest, IExtraData, IResponse, IExtraData>

    //OK
    res.Services.Add(service as IResellerService<IRequest, IExtraData, IResponse, IExtraData>);
}

好吧,我可能会错过一些继承或接口实现的基本概念,但是我做错了什么?

希望你能解决我的需求。

1 个答案:

答案 0 :(得分:3)

我认为你在这里遇到的问题是,尽管这种方式很好并且很好地抛出接口,如果你有一个接口,你真的需要一些东西来消费那个接口。你还没有这样做,你通过实现该接口专门设计了一个类型,但是哪种类型将直接使用该接口作为输入?这是一个例子:

public interface IService<TModel>
{
  TModel Get(string id);
}

public class MyService : IService<MyModel>
{
  public MyModel Get(string id)
  {
    // Work
  }
}

var service = new MyService();
var model = service.Get("something");

上面,虽然我已经为服务定义了一个接口,但实际上我并没有在代码中依赖该服务。我仍然依赖于IService<TModel>MyService的具体实现。

我的代码不应该关心MyService是什么,它应该只关心它可以支持IService<TModel>定义的操作。如果我们重构了这个:

public class ModelFactory<TModel>
{
  IService<TModel> _service;

  public ModelFactory(IService<TModel> service)
  {
    _service = service;
  }

  public TModel Get(string code)
  {
    return _service.Get(code);
  }

}

现在我有一个可以使用我的界面的类,并允许我将实现与我的代码分开:

var factory = new ModelFactory<MyModel>(new MyService());
var model = factory.Get("something");

通常你会使用IoC / DI来注入依赖项,但我希望这是一个明显的例子。