##// END OF EJS Templates
code cleanup and refactoring
code cleanup and refactoring

File last commit:

r281:e0916ddc9950 v3
r281:e0916ddc9950 v3
Show More
FactoryElement.cs
72 lines | 3.8 KiB | text/x-csharp | CSharpLexer
using System;
using System.Xml.Serialization;
using Implab.Components;
namespace Implab.ServiceHost.Unity {
/// <summary>
/// Расширяет стандартную регистрацию типа до фабрики, вместе с регистрацией
/// самой фабрики создаются регистрации сервисов, которые она предоставляет.
/// </summary>
public class FactoryElement : RegisterElement, ITypeRegistration {
/// <summary>
/// Записи о сервисах, которые создаются данной фабрикой.
/// </summary>
/// <remarks>
/// Сервисы, которые указаны в регистарциях они должны соответсвовать тому,
/// что фабрика возвращает, но это остается на откуп контейнера
/// </remarks>
[XmlElement("provides")]
public ProvidesElement[] Provides { get; set; }
/// <summary>
/// Переопределяет стандарное поведение регистрации типа в контейнере,
/// дополняя его регистрацией фабричных методов для получения типов.
/// </summary>
/// <param name="builder">Объект для конфигурирования контейнера.</param>
public override void Visit(ContainerBuilder builder) {
var factoryType = GetRegistrationType(builder.ResolveType);
base.Visit(builder);
if (Provides != null && Provides.Length > 0) {
// если регистрации явно заданы, используеися информация из них
foreach(var item in Provides) {
var activator = new FactoryActivator {
Name = item.RegistrationName,
RegistrationType = builder.ResolveType(item.RegistrationType),
FactoryName = Name,
FactoryType = factoryType,
Lifetime = item.Lifetime.GetLifetime(builder)
};
builder.Visit(activator);
}
} else {
// если регистрация явно не задана, в качестве сервиса для регистрации
// используется тип создаваемый фабрикой, который будет добавлен в контейнер
// с темже именем, что и сама фабрика (разные типы могут иметь одно имя для регистрации)
var providedType = (
factoryType.IsGenericType && factoryType.GetGenericTypeDefinition() == typeof(IFactory<>) ?
factoryType :
factoryType.GetInterface(typeof(IFactory<>).FullName)
)?
.GetGenericArguments()[0];
// не удалось определеить тип
if (providedType == null)
throw new ArgumentException("Failed to determine a type provided by the factory");
if (providedType.IsGenericParameter)
throw new ArgumentException("Can't register a generic type paramter as a service");
var activator = new FactoryActivator {
Name = Name,
RegistrationType = providedType,
FactoryName = Name,
FactoryType = factoryType
};
builder.Visit(activator);
}
}
}
}