2010-10-22 1 views
2

Мне нужно ввести коллекцию типа IList<IActivity> в конструктор. Я использую Unity 2.0 и настраиваю его с помощью XML.Как вставить общий IList <> объектов с использованием Unity 2 XML config?

Я смог сделать это, просто введя массив в 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 ».

Если я полностью удаляю атрибут типа из элемента конструктора, я получаю такое же сообщение об ошибке, как указано выше.

Единственный способ, которым я могу заставить это работать, - это изменить конструктор, чтобы вместо этого принять массив IActivity [].

Так это ошибка в Unity, поскольку массив является IList и должен найти конструктор? Или мне что-то не хватает в моей конфигурации?

+0

Большой , Я только что получил значок Tumbleweed для этого! Может ли кто-нибудь помочь? – freshr

+0

Вы когда-нибудь это выясняли? –

ответ

1

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

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

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

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

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

+0

Формат '1 [[MyProject.IActivity, MyProject]] очень трудно найти. Спасибо, что опубликовали это! Я согласен, однако, что его трудно поддерживать, но в некоторых случаях альтернативы нет :-( – Pandincus

2

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

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».

Сначала вам нужно подготовить свой конфигурационный файл, в этом случае он использует подписанные ссылки на 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> 

Используйте контейнер для разрешения зависимости ;-)

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

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