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 } |