Использование iBATIS.NET с универсальными пользовательскими интерфейсами коллекций и Unity

Я пытаюсь использовать общий пользовательский интерфейс коллекции (для поддержки внедрения с Microsoft Patterns and Practices Unity) в классе O/R, сопоставленном с iBATIS.NET. Кто-нибудь знает, возможно ли это, и если да, то как это сделать?

У меня есть интерфейс IDataItemCollection‹T›, который я сопоставляю с SqlDataItemCollection‹T›, который расширяет CollectionBase. Я хочу использовать IDataItemCollection‹T› в своих классах, чтобы можно было поменять местами SqlDataItemCollection‹T› с другими классами, которые расширяют интерфейс через Unity. Файл сопоставления iBATIS.NET может напрямую ссылаться на конкретный класс, поскольку одно не может существовать без другого.

Ниже я привел очень упрощенный пример кода, базы данных и отображений. Я совершенно новичок в iBATIS.NET и на самом деле просто хочу доказать его использование в данный момент, поэтому, пожалуйста, при необходимости измените XML-код сопоставления.

Большое спасибо,

Павел


Код С#

public interface IDataItem
{
    object Id { get; set; }
}

public class DataItem : IDataItem
{
    public object Id { get; set; }
}

public interface IDataItemCollection<T> : ICollection where T : IDataItem
{
    // Various Getters and Setters
...
}

public class SqlDataItemCollection<T> : CollectionBase, IDataItemCollection<T> where T : DataItem
{
    public SqlDataItemCollection() { }
    public SqlDataItemCollection(T injType) { }

    // Getters and Setters to implement interfaces
...
}

public class Foo : DataItem
{
    public Foo(IDataItemCollection<Bar> bars)
    {
        Bars = bars;
    }

    public IDataItemCollection<Bar> Bars { get; set; }
}

public class Bar : DataItem { }

База данных SQL Server 2005

CREATE TABLE Foo
(
    Id bigint IDENTITY(1,1)
)

CREATE TABLE Bar
(
    Id bigint IDENTITY(1,1)
)

CREATE TABLE FooBar
(
    FooId bigint,
    BarId bigint
)

iBATIS.NET Mapping.xml

<resultMaps>
    <resultMap id="FooResult" class="Foo">
        <result property="Id" column="Id"/>
        <result property="Bars" column="Id" select="SelectBarsInFoo" lazyLoad="false"/>
    </resultMap>

    <resultMap id="BarResult" class="Bar">
        <result property="Id" column="Id"/>
    </resultMap>
</resultMaps>

<statements>
    <select id="SelectFoo" resultMap="FooResult">
        SELECT Id
        FROM Foo
    </select>

    <select id="SelectBarsInFoo" parameterClass="long" resultMap="BarResult" listClass="SqlDataItemCollection`1[Bar]" >
        SELECT Bar.Id
        FROM Bar
        JOIN FooBar ON Bar.Id = FooBar.BarId
        WHERE FooBar.FooId = #value#
    </select>
</statements>

person tRi11    schedule 02.03.2009    source источник
comment
Проблема, похоже, в том, что я использую интерфейс вместо конкретного класса. Замена IDataItemCollection‹Bar› на SqlDataItemCollection‹Bar› приводит к тому, что все работает должным образом, к сожалению, мне нужна возможность поменять местами конкретные классы с Unity. Является ли это ограничением iBATIS.NET?   -  person tRi11    schedule 03.03.2009


Ответы (1)


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

public interface IGroup { }
public class Group : IGroup { }
public class IGroupCollection : IList<IGroup> { }
public class GroupCollection : IGroupCollection { }

public interface IConcrete
{
    IGroupCollection Items { get; set; }
}

public class Concrete : IConcrete
{
    public GroupCollection Items { get; set; }
    IGroupCollection IConcrete.Items
    {
        get { return Items; }
        set { Items = value as GroupCollection; }
    }
}

Это позволяет iBATIS.NET добавлять элементы в коллекцию, не сталкиваясь с ошибкой преобразования типа, в то время как явная реализация интерфейса позволяет мне использовать IConcrete в моем приложении, не обращаясь к фактическим Concrete или фактическим GroupCollection.

person cfeduke    schedule 01.07.2010