Mercurial > pub > ImplabNet
comparison Implab.ServiceHost/Unity/FactoryElement.cs @ 278:6691aff01de1 v3
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)
Implab.ServiceHost: rewritten TypeReference (added support for nested types), stable API
| author | cin |
|---|---|
| date | Thu, 03 May 2018 09:59:44 +0300 |
| parents | |
| children | 8714471e8d78 |
comparison
equal
deleted
inserted
replaced
| 277:963b17c275be | 278:6691aff01de1 |
|---|---|
| 1 using System; | |
| 2 using System.Xml.Serialization; | |
| 3 using Implab.Components; | |
| 4 | |
| 5 namespace Implab.ServiceHost.Unity { | |
| 6 /// <summary> | |
| 7 /// Расширяет стандартную регистрацию типа до фабрики, вместе с регистрацией | |
| 8 /// самой фабрики создаются регистрации сервисов, которые она предоставляет. | |
| 9 /// </summary> | |
| 10 public class FactoryElement : RegisterElement { | |
| 11 | |
| 12 /// <summary> | |
| 13 /// Записи о сервисах, которые создаются данной фабрикой. | |
| 14 /// </summary> | |
| 15 /// <remarks> | |
| 16 /// Сервисы, которые указаны в регистарциях они должны соответсвовать тому, | |
| 17 /// что фабрика возвращает, но это остается на откуп контейнера | |
| 18 /// </remarks> | |
| 19 [XmlElement("provides")] | |
| 20 public ProvidesElement[] Provides { get; set; } | |
| 21 | |
| 22 /// <summary> | |
| 23 /// Переопределяет стандарное поведение регистрации типа в контейнере, | |
| 24 /// дополняя его регистрацией фабричных методов для получения типов. | |
| 25 /// </summary> | |
| 26 /// <param name="builder">Объект для конфигурирования контейнера.</param> | |
| 27 public override void Visit(ContainerBuilder builder) { | |
| 28 var factoryType = GetRegistrationType(builder.ResolveType); | |
| 29 | |
| 30 base.Visit(builder); | |
| 31 | |
| 32 if (Provides != null && Provides.Length > 0) { | |
| 33 // если регистрации явно заданы, используеися информация из них | |
| 34 foreach(var item in Provides) { | |
| 35 var activator = new FactoryActivator { | |
| 36 Name = item.RegistrationName, | |
| 37 RegistrationType = builder.ResolveType(item.RegistrationType), | |
| 38 FactoryName = Name, | |
| 39 FactoryType = factoryType | |
| 40 }; | |
| 41 activator.Visit(builder); | |
| 42 } | |
| 43 } else { | |
| 44 // если регистрация явно не задана, в качестве сервиса для регистрации | |
| 45 // используется тип создаваемый фабрикой, который будет добавлен в контейнер | |
| 46 // с темже именем, что и сама фабрика (разные типы могут иметь одно имя для регистрации) | |
| 47 var providedType = ( | |
| 48 factoryType.IsGenericType && factoryType.GetGenericTypeDefinition() == typeof(IFactory<>) ? | |
| 49 factoryType : | |
| 50 factoryType.GetInterface(typeof(IFactory<>).FullName) | |
| 51 )? | |
| 52 .GetGenericArguments()[0]; | |
| 53 | |
| 54 // не удалось определеить тип | |
| 55 if (providedType == null) | |
| 56 throw new ArgumentException("Failed to determine a type provided by the factory"); | |
| 57 | |
| 58 if (providedType.IsGenericParameter) | |
| 59 throw new ArgumentException("Can't register a generic type paramter as a service"); | |
| 60 | |
| 61 var activator = new FactoryActivator { | |
| 62 Name = Name, | |
| 63 RegistrationType = providedType, | |
| 64 FactoryName = Name, | |
| 65 FactoryType = factoryType | |
| 66 }; | |
| 67 | |
| 68 activator.Visit(builder); | |
| 69 } | |
| 70 } | |
| 71 } | |
| 72 } |
