views:

129

answers:

2

Hi guys!

I've got a hypothetical Reseller who can supply some Services; all Services are same: they threat some IRequest data, plus some IExtraData, and provide an IResponse.

Please read this code (working on 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>);
}

Well, probably I miss some of base concepts of inheritance or interface implementation, but what I'm doing it wrong?

Hope you can undestand my needs.

+3  A: 

I think the problem you will run into here, is that, although it's all well and good throwing interfaces together this way, if you have an interface, you really need something to consume that interface. You haven't done that, you've specialised a type by implementing that interface, but what types are going to use that interface as an input directly? Here is an example:

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");

Above, although I've defined an interface for a service, I'm not actually dependant on that service in code. I'm still dependant on the concrete implementation of IService<TModel>: MyService.

My code shouldn't care what MyService is, it should only care that it can support the operations defined by IService<TModel>. If we had refactored this:

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

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

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

}

Now I have a class which can consume my interface, and allows me to decouple the implementation away from my code:

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

Typically you'd do something with IoC/DI to inject the dependency, but I hope this is a clear example.

Matthew Abbott
Matthew, your Factory solution is a good one.After lunch (here in Italy it's half past midday :-) ) I would give it a try.Thank you!
Ferdinando Santacroce
+1  A: 

Check out http://stackoverflow.com/questions/3872988/interfaces-inheritance-in-c/3873436#3873436

Grozz
Very interesting, Grozz; I was trying to do some like this, but with no success. After lunch I will try this solution, too.Thank you!
Ferdinando Santacroce