Первые шаги с Unity Application Block - Part 2
В продолжении темы расмотрим как использовать generic типы в Unity.
Создадим вот такой интерфейс и класс к нему:
public interface IMessenger<T> : IMessenger { } public class Messenger<T> : IMessenger { public string Message { get { return String.Format("Messenger<{0}>", typeof(T).Name); } } }
также модифицируем конфигурационный файл:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration" requirePermission="false"/> </configSections> <unity> <typeAliases> <typeAlias alias="IMessenger" type="UnityAppBlock.IMessenger, UnityAppBlock"/> <typeAlias alias="Messenger" type="UnityAppBlock.Messenger, UnityAppBlock"/> <typeAlias alias="IMessengerT" type="UnityAppBlock.IMessenger`1, UnityAppBlock"/> <typeAlias alias="MessengerT" type="UnityAppBlock.Messenger`1, UnityAppBlock"/> </typeAliases> <containers> <container> <types> <type type="IMessenger" mapTo="Messenger"/> <type type="IMessengerT" mapTo="MessengerT"/> </types> </container> </containers> </unity> </configuration>
как видим, чтобы сказать что типа является generic нужно поставить знак ` после которого идет количество типов.
И добавим код в ф-цию Main:
static void Main(string[] args) { IUnityContainer container = new UnityContainer(); var section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity"); section.Containers.Default.Configure(container); IMessenger messenger = container.Resolve<IMessenger>(); Console.WriteLine(messenger.Message); Console.WriteLine("\n-- Generic --"); messenger = container.Resolve<IMessenger<int>>() as IMessenger; Console.WriteLine(messenger.Message); messenger = container.Resolve<IMessenger<double>>() as IMessenger; Console.WriteLine(messenger.Message); messenger = container.Resolve<IMessenger<string>>() as IMessenger; Console.WriteLine(messenger.Message); Console.ReadLine(); }
На экране увидим следующие:
Just messenger -- Generic -- Messenger<Int32> Messenger<Double> Messenger<String>
--------------------------------------------------------------------------------------------------------
Интересный вопрос.. а как сделать так, что когда мы запросим в Unity IMessenger
Давайте попробуем реализовать это..
создадим класс:
public class MessengerString : IMessenger<string> { public string Message { get { return "MessengerString"; } } }
и также модифицируем app.config:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration" requirePermission="false"/> </configSections> <unity> <typeAliases> <typeAlias alias="IMessenger" type="UnityAppBlock.IMessenger, UnityAppBlock"/> <typeAlias alias="Messenger" type="UnityAppBlock.Messenger, UnityAppBlock"/> <typeAlias alias="IMessengerT" type="UnityAppBlock.IMessenger`1, UnityAppBlock"/> <typeAlias alias="MessengerT" type="UnityAppBlock.Messenger`1, UnityAppBlock"/> <typeAlias alias="IMessengerOfString" type="UnityAppBlock.IMessenger`1[[System.String, mscorlib]], UnityAppBlock"/> <typeAlias alias="MessengerOfString" type="UnityAppBlock.MessengerString, UnityAppBlock"/> </typeAliases> <containers> <container> <types> <type type="IMessenger" mapTo="Messenger"/> <type type="IMessengerT" mapTo="MessengerT"/> <type type="IMessengerOfString" mapTo="MessengerOfString"/> </types> </container> </containers> </unity> </configuration>
как видите, чтобы обьявить тип в generic класса, нужно его написать в двойных квадратных скобкаx [[Namespace.Class, Assambly]], после `1
ф-цию Main оставим без изменений... и в результате при запуске мы получим следующие:
Just messenger -- Generic -- Messenger<Int32> Messenger<Double> MessengerString
как видим вместо Messenger
--------------------------------------------------------------------------------------------------------
Расмотрим пример, когда generic класс состоит из двух типов:
public interface IMessenger<T, T2> : IMessenger { } public class DoubleMessenger<T, T2> : IMessenger<T, T2> { public string Message { get { return String.Format("DoubleMessenger<{0}, {1}>", typeof(T).Name, typeof(T2).Name); } } }
app.config:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration" requirePermission="false"/> </configSections> <unity> <typeAliases> <typeAlias alias="IMessenger" type="UnityAppBlock.IMessenger, UnityAppBlock"/> <typeAlias alias="Messenger" type="UnityAppBlock.Messenger, UnityAppBlock"/> <typeAlias alias="IMessengerT" type="UnityAppBlock.IMessenger`1, UnityAppBlock"/> <typeAlias alias="MessengerT" type="UnityAppBlock.Messenger`1, UnityAppBlock"/> <typeAlias alias="IMessengerOfString" type="UnityAppBlock.IMessenger`1[[System.String, mscorlib]], UnityAppBlock"/> <typeAlias alias="MessengerOfString" type="UnityAppBlock.MessengerString, UnityAppBlock"/> <typeAlias alias="IMessengerDoubleT" type="UnityAppBlock.IMessenger`2, UnityAppBlock"/> <typeAlias alias="MessengerDoubleT" type="UnityAppBlock.DoubleMessenger`2, UnityAppBlock"/> </typeAliases> <containers> <container> <types> <type type="IMessenger" mapTo="Messenger"/> <type type="IMessengerT" mapTo="MessengerT"/> <type type="IMessengerOfString" mapTo="MessengerOfString"/> <type type="IMessengerDoubleT" mapTo="MessengerDoubleT"/> </types> </container> </containers> </unity> </configuration>
Main:
static void Main(string[] args) { IUnityContainer container = new UnityContainer(); var section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity"); section.Containers.Default.Configure(container); IMessenger messenger = container.Resolve<IMessenger>(); Console.WriteLine(messenger.Message); Console.WriteLine("\n-- Generic --"); messenger = container.Resolve<IMessenger<int>>() as IMessenger; Console.WriteLine(messenger.Message); messenger = container.Resolve<IMessenger<double>>() as IMessenger; Console.WriteLine(messenger.Message); messenger = container.Resolve<IMessenger<string>>() as IMessenger; Console.WriteLine(messenger.Message); Console.WriteLine("\n-- Double Generic --"); messenger = container.Resolve<IMessenger<int, string>>() as IMessenger; Console.WriteLine(messenger.Message); messenger = container.Resolve<IMessenger<DateTime, Guid>>() as IMessenger; Console.WriteLine(messenger.Message); Console.ReadLine(); }
Output будет:
Just messenger -- Generic -- Messenger<Int32> Messenger<Double> MessengerString -- Double Generic -- DoubleMessengerDoubleMessenger
--------------------------------------------------------------------------------------------------------
Дальше попробуем сделать, чтобы при запросе типа IMessenger
public class GuidLongMessenger : IMessenger<Guid, long> { public string Message { get { return "GuidLongMessenger"; } } }
в app.config добавим:
<typeAlias alias="IMessengerGuidLong" type="UnityAppBlock.IMessenger`2[[System.Guid, mscorlib], [System.Int64, mscorlib]], UnityAppBlock"/> <typeAlias alias="MessengerGuidLong" type="UnityAppBlock.GuidLongMessenger, UnityAppBlock"/> <type type="IMessengerGuidLong" mapTo="MessengerGuidLong"/>
Main:
messenger = container.Resolve<IMessenger<Guid, long>>() as IMessenger; Console.WriteLine(messenger.Message);
Output:
Just messenger -- Generic -- Messenger<Int32> Messenger<Double> <strong>MessengerString</strong> -- Double Generic -- DoubleMessenger<Int32, String> DoubleMessenger<DateTime, Guid> GuidLongMessenger
--------------------------------------------------------------------------------------------------------
Вот и все.. мы научились определять generic типы в xml файле для Unity (сам я потратил причный отрезок времени на поиск решения этой проблемы.. надеюсь мне удалось сохранить ваше))))
WBR,
Bobasoft
Компании из статьи
Microsoft Украина | Украинское подразделение компании Microsoft. |