使用iBATIS.NET与通用自定义集合接口和Unity [英] Using iBATIS.NET with generic custom collection interfaces and Unity
问题描述
我在使用iBATIS.NET映射的类O / R中尝试使用通用自定义收集界面(支持Microsoft模式和惯例Unity注入)。有没有人知道这是否可能,如果是这样,怎么办?
I'm trying to use a generic custom collection interface (to support injection with Microsoft Patterns and Practices Unity) in a class O/R mapped with iBATIS.NET. Does anyone know if this is possible and if so how to do it?
我有一个IDataItemCollection< T>我映射到SqlDataItemCollection< T>这扩展了CollectionBase。我想使用IDataItemCollection< T>在我的类,所以我可以交换SqlDataItemCollection< T>与通过Unity扩展接口的其他类。 iBATIS.NET映射文件可以直接引用具体类,因为没有其他类。
I have an IDataItemCollection<T> interface that I map to SqlDataItemCollection<T> which extends CollectionBase. I want to use the IDataItemCollection<T> in my classes so I can swap SqlDataItemCollection<T> with other classes that extend the interface through Unity. The iBATIS.NET mapping file can reference the concrete class directly as there won't be one without the other.
下面我包含了一个非常简化的代码示例,数据库和映射。我对iBATIS.NET完全陌生,真的只是想证明它的使用,所以请根据需要重新绘制映射XML。
Below I have included a very simplified example of the code, database and mappings. I'm completely new to iBATIS.NET and really just want to prove its use at the moment, so please re-jig the mapping XML as necessary.
非常感谢,
Paul
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数据库
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
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>
推荐答案
我的应用程序回到接口。我通过明确实现接口的定义我的集合,然后复制实现作为其具体类绕过它。这可能无法解决您的问题。
I just had this same problem after refactoring a portion of my application back to interfaces. I got around it by explicitly implementing the interface's definition of my collection and then duplicating the implementation as its concrete class. This may not solve your problem.
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
。
This allows iBATIS.NET to add items to the collection without running into a type conversion error while the explicit interface implementation allows me to use the IConcrete
s throughout my app without referring to the actual Concrete
or actual GroupCollection
.
这篇关于使用iBATIS.NET与通用自定义集合接口和Unity的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!