Реализация интерфейса C #: все правильно - PullRequest
1 голос
/ 18 октября 2010

У меня есть гипотетический Торговый посредник, который может предоставить некоторые Услуги; все сервисы одинаковы: они угрожают некоторым данным 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 Ответ

3 голосов
/ 18 октября 2010

Я думаю, что проблема, с которой вы здесь столкнетесь, заключается в том, что, хотя все это хорошо и хорошо объединяет интерфейсы, если у вас есть интерфейс, вам действительно нужно что-то, чтобы потреблял этот интерфейс.Вы этого не сделали, вы специализировали тип, реализовав этот интерфейс, но какие типы будут использовать этот интерфейс в качестве входных данных напрямую?Вот пример:

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, чтобы добавить зависимость, но я надеюсь, что это яркий пример.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...