Рефакторинг для получения правильного наследования / интерфейсов / согласованности - PullRequest
0 голосов
/ 10 августа 2011

РЕДАКТИРОВАТЬ: я добавил эквиваленты C #, чтобы привлечь более широкую аудиторию - надеюсь, что все в порядке

VS2008 - .Net 3.5 (поэтому я не получаю поддержку согласованности / контравариантности, насколько я знаю?)

Похоже, что для этого, скорее всего, потребуются согласие / контравариантность и, следовательно, .Net 4, поэтому, чтобы предотвратить невозможность ответа на этот вопрос, не стесняйтесь отвечать за .Net4, хотя я бы предпочел простой рефакторинг.если он доступен.

Это должно быть просто, но по какой-то причине мой мозг просто не готов (сегодня?) к вызову этим утром.

У меня есть 2 заявки (AИ б).Детали приложения Надеемся, что это не важно, поэтому ниже приводится WRT AppB, который имеет 3 проекта, все библиотеки классов:

  1. Предоставляет мои доменные сущности остальной части AppB, а также предоставляется AppA
  2. Предоставляет мою модель данных только для AppB (использует L2S, обычный контекст и сущности)
  3. Предоставляет функциональность AppA, используя доменные объекты для параметров / типов возврата

У меня есть следующие интерфейсы в 3 разных проектах:

В проекте 1 (доменные объекты)

VB:

Public Interface IAppB_Project1_Contract(Of TKey)
     ReadOnly Property UniqueReference As TKey
End Interface

C #

public interface IAppB_Project1_Contract<TKey>
{
    TKey UniqueReference { get; }
}

В проекте 2 (модель данных)

VB:

Public Interface IAppB_Project2_Contract(Of TKey)
     Inherits IAppB_Project1_Contract(Of TKey)
End Interface

C #:

public interface IAppB_Project2_Contract<TKey> : IAppB_Project1_Contract<TKey>
{
}

В проекте 3 (функциональность)

VB:

Public Interface IAppB_Project3_Contract
     Function Create(Of T As {Class, IAppB_Project1_Contract(Of TKey)}, TKey)(ByVal entity As T) As TKey
End Interface

C #:

public interface IAppB_Project3_Contract
{
    TKey Create<T, TKey>(T entity) where T : class, IAppB_Project1_Contract<TKey>;
}

Идея заключалась в том, что контракты функциональности (в проекте 3) будут использовать только доменные объекты (в проекте 1) какаргументы / возвраты, потому что только проекты 1 и 3 открыты для приложения A, проект 2 - нет.

Мои права на L2Ss расширены для реализации интерфейса Project 2.Есть фактически несколько дополнительных методов в контракте Проекта 2, но мы надеемся, что они не имеют отношения к делу.

До тех пор, пока я фактически не набрал его, по какой-то причине у меня было в голове, что я сойду с рук при следующей реализации контракта Проекта 3:

VB:

Public Class Project3_Implementation
    Implements IAppB_Project3_Contract

    Public Function Create(Of T As {Class, IApp_Project2_Contract(Of TKey)}, TKey)(ByVal entity As T) As TKey Implements IAppB_Project3_Contract.Create
        ' notice the very subtle change to *Project TWO's* contract in the generics' constraint
    End Function
End Class

C #:

public class Project3_Implementation : IAppB_Project3_Contract
{
    public TKey Create<T, TKey>(T entity) where T : class, IApp_Project2_Contract<TKey>
    {
        // notice the very subtle change to *Project TWO's* contract in the generics' constraint
    }
}

Это работало в моей голове некоторое время, потому что контракт проекта 2 наследует проект 1, но это, конечно, недело в том, что я сузил ограничение, которое поэтому не может реализовать соответствующий интерфейс проекта 3.

Вопрос в том, как мне поступить, чтобы добиться того, что я искал:

  • Проект 2 должен оставаться невидимым для Приложения A, однако Проект 1 и 3 подвержен воздействию и должен описывать доступные функциональные возможности и объекты, которые Приложение A может / должно использовать для вызова Приложения B
  • Реализация.контракта проекта 3, в идеале, параметры ограничиваются тем, чтобы быть фактически объявленнымив скрытом проекте 2.

У меня есть чувство, что я спрашиваю о невозможном, но я надеюсь, что кто-то за пределами коробки, смотрящий внутрь, может предложить что-то, чего я могу изменить, или прийтиблизко к достижению моих целей?

Спасибо заранее !!

РЕДАКТИРОВАТЬ:

Я знал, что вопрос не будет ясным, потому что я описал в этом вопросепросто как сделать что-то не так ...

Вот более подробная информация о реализации контракта проекта 3, которая, как мы надеемся, прояснит ситуацию (имея в виду, что контракт проекта 2 реализован только автоматическисгенерированные сущности Linq):

VB:

Public Class MyImplementation
    Inherits System.Data.Linq.DataContext
    Implements IAppB_Project3_Contract

    Public Function Create(Of T As {Class, IApp_Project2_Contract(Of TKey)}, TKey)(ByVal entity As T) As TKey Implements IAppB_Project3_Contract.Create
        Me.GetTable(Of T).InsertOnSubmit(entity)
        Return entity.UniqueReference        ' the entity will implement the IApp_Project2_Contract by exposings it primary key - Return Me.MyPrimaryKeyField
    End Function
End Class

C #:

public class MyImplementation : System.Data.Linq.DataContext, IAppB_Project3_Contract
{
    public TKey Create<T, TKey>(T entity) where T : class, IApp_Project2_Contract<TKey>
    {
        this.GetTable<T>.InsertOnSubmit(entity);
        return entity.UniqueReference;
        // the entity will implement the IApp_Project2_Contract by exposings it primary key - Return Me.MyPrimaryKeyField
    }
}

1 Ответ

1 голос
/ 10 августа 2011

Что произойдет, если вы объявите, что ваши интерфейсы подобны этому, для этого потребуется .Net 4.0 +

Public Interface IAppB_Project1_Contract(Of Out TKey)
    ReadOnly Property UniqueReference As TKey 
End Interface

Public Interface IAppB_Project2_Contract(Of Out TKey)
    Inherits IAppB_Project1_Contract(Of TKey)
End Interface

Public Interface IAppB_Project3_Contract
    Function Create(Of T As {Class, IAppB_Project1_Contract(Of TKey)}, 
                    TKey)(ByVal entity As T) As TKey       
End Interface

Не сделает ли это наследники интерфейсов ковариантными по отношению к родительским типам и разрешить выполнение кода?1004 *

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