2009-03-02 2 views
1

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

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

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

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

Пол


C# Код

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 Database

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> 
+0

Проблема заключается в том, что я использую интерфейс вместо конкретного класса. Замена IDataItemCollection с SqlDataItemCollection заставляет все работать должным образом, к сожалению, мне нужна возможность обменивать конкретные классы с Unity. Является ли это ограничением iBATIS.NET? – tRi11

ответ

0

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

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.

Смежные вопросы