Как внедрить общий IList <> объектов, используя конфигурацию Unity 2 XML? - PullRequest
2 голосов
/ 22 октября 2010

Мне нужно добавить коллекцию типа 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 ]

2 голосов
/ 08 ноября 2010

На самом деле вы можете попытаться применить псевдоним вместо наследования к новому типу.

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

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

Кстати, в этой статье есть объяснение вариантов использования дженериков ;-) http://dotnetslackers.com/articles/net/A-First-Look-at-Unity-2-0.aspx Я надеюсь, что это поможет

EDIT :

После некоторого времени, потраченного на его использование, вот мой ответ: Список Предположим, вы хотите использовать разрешение от «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();
        }
    }
}

Этого должно быть достаточно, я надеюсь, что это работает ;-) С наилучшими пожеланиями, Herber

1 голос
/ 31 октября 2010

Что бы я сделал, это создал бы ActivityList типа, производный от IList<IActivity>.

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

Такие вещи внутри файла конфигурации:

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

трудно понять и поддерживать.

...