如何注入通用IList<>使用Unity 2 XML配置的对象?

时间:2010-10-22 11:17:36

标签: unity-container

我需要将一个类型为IList<IActivity>的集合注入构造函数中。我正在使用Unity 2.0并使用XML进行配置。

我能够通过在Unity 1.2中注入一个数组来实现这一点。我刚刚升级到Unity 2.0,我的配置现在已停止在此特定区域工作。 (我已经解决了对模式的所有微不足道的更改。)

我的构造函数如下所示:

public DoSomethingWorkflow(IList<IActivity> activityCollection)
{
  ...
}

我的配置如下:

<alias alias="IListOfIActivity" type="System.Collections.Generic.IList`1[[MyProject.IActivity, MyProject]], mscorlib"/>

<alias alias="IActivityArray" type="MyProject.IActivity[], MyProject" />

<register type="IWorkflow" mapTo="Workflow" name="DoSomethingWorkflow">
    <constructor>
      <param name="activityCollection" type="IListOfIActivity">
        <array>
          <dependency name="DoSomethingActivity1"/>
          <dependency name="DoSomethingActivity2"/>
        </array>
      </param>
    </constructor>     
</register>

如果我按上面那样运行配置,我会收到一条错误消息“配置设置为注入数组,但类型IList`1不是数组类型”。

如果我将其更改为以前的工作方式(注入类型别名IActivityArray),我会收到一条错误消息“配置不正确,MyProject.Workflow类型没有带有名为activityCollection的参数的构造函数”。

如果我完全从构造函数元素中删除了type属性,我会收到与上面相同的错误消息。

我能让它工作的唯一方法是改变构造函数来接受IActivity []数组。

这是Unity中的一个错误,因为数组是IList并且应该找到构造函数?或者我在配置中遗漏了什么?

2 个答案:

答案 0 :(得分:2)

实际上,您可以尝试应用别名而不是继承到新类型。

using  ActivityList=System.Collections.Generic.List<IActivity>;
//.... after some declarations
var activityList = new ActivityList();

我一直在阅读有关Unity配置文件的内容。我知道你可以创建别名,但我不确定如何指定泛型

BTW本文解释了使用泛型的选项;-) http://dotnetslackers.com/articles/net/A-First-Look-at-Unity-2-0.aspx 我希望这有帮助

修改

花了一些时间尝试使用它,这是我的答案: 列表假设您要使用从“IList”到“List”的解析。

1 首先,您必须准备配置文件,在这种情况下,它使用对IList和List的签名引用。


<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration"/>
  </configSections>
  <unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
    <alias alias="StringListContract" type="System.Collections.Generic.IList`1[[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
    <alias alias="ConcreteStringList" type="System.Collections.Generic.List`1[[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
    <container>
      <register type="StringListContract" mapTo="ConcreteStringList">
        <lifetime type="ContainerControlledLifetimeManager" />
        <constructor />
      </register>
    </container>
  </unity>
</configuration>

<强> 2 使用容器来解决依赖关系; - )

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;
namespace UnityTerminal
{


    class Program
    {
        static void Main(string[] args)
        {
            var container = new UnityContainer();
            container.LoadConfiguration();
            {
                var concreteStringList = container.Resolve<System.Collections.Generic.IList<System.String>>();
                concreteStringList.Add("Hello World");
            }
            {
                var concreteStringList = container.Resolve<System.Collections.Generic.IList<System.String>>();
                Console.WriteLine("{0}", concreteStringList[0]);
            }
            Console.ReadKey();
        }
    }
}

那应该够了,我希望这个有用;-) 最好的祝福, 数量锐减

答案 1 :(得分:1)

我要做的是创建一个派生自IList<IActivity>

的ActivityList
class ActivityList : IList<IActivity>
{ /* */ }

配置文件中的这种东西:

System.Collections.Generic.IList`1[[MyProject.IActivity, MyProject]], mscorlib

很难理解和维护。