2009-03-02 9 views
1

Ich versuche, eine generische benutzerdefinierte Sammlung Schnittstelle (um die Injektion mit Microsoft Patterns und Practices Unity zu unterstützen) in einer Klasse O/R zugeordnet mit iBATIS.NET. Weiß jemand, ob das möglich ist und wenn ja, wie?Verwendung von iBATIS.NET mit generischen benutzerdefinierten Collection-Schnittstellen und Unity

Ich habe eine IDataItemCollection <T> Schnittstelle, die ich SqlDataItemCollection <T> Karte, die Collection erstreckt. Ich möchte die IDataItemCollection <T> in meinen Klassen verwenden, damit ich SqlDataItemCollection <T> mit anderen Klassen austauschen kann, die die Schnittstelle durch Unity erweitern. Die iBATIS.NET-Mapping-Datei kann direkt auf die konkrete Klasse verweisen, da die eine nicht ohne die andere existiert.

Im Folgenden habe ich ein sehr vereinfachtes Beispiel für den Code, die Datenbank und Mappings enthalten. Ich bin völlig neu bei iBATIS.NET und möchte seine Nutzung im Moment nur beweisen, also passen Sie das Mapping-XML nach Bedarf an.

Vielen Dank,

Paul


C# -Code

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 Datenbank

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

Das Problem scheint zu sein, weil ich eine Schnittstelle anstelle einer konkreten Klasse verwende. Ersetzen IDataItemCollection mit SqlDataItemCollection bewirkt, dass alles wie erwartet funktioniert, leider brauche ich die Möglichkeit, die konkreten Klassen mit Unity zu tauschen. Ist dies eine Einschränkung von iBATIS.NET? – tRi11

Antwort

0

Ich hatte gerade das gleiche Problem, nachdem ein Teil meiner Anwendung zurück zu Schnittstellen Refactoring. Ich habe es umgangen, indem ich die Definition meiner Schnittstelle explizit implementiert habe und die Implementierung dann als ihre konkrete Klasse dupliziert habe. Dies kann Ihr Problem möglicherweise nicht lösen.

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; } 
    } 
} 

Dies ermöglicht iBATIS.NET Elemente in die Sammlung hinzuzufügen, ohne in einen Typ-Konvertierungsfehler ausgeführt, während die explizite Schnittstellenimplementierung ermöglicht es mir, die IConcrete s während meiner App zu nutzen, ohne auf die tatsächlichen Concrete oder tatsächlichen GroupCollection bezieht.