Auto status change to "Under Review"
@@ -0,0 +1,12 | |||
|
1 | using System; | |
|
2 | using System.Xml.Serialization; | |
|
3 | ||
|
4 | namespace Implab.ServiceHost.Unity { | |
|
5 | public abstract class AbstractInjectionParameter : IInjectionParameter { | |
|
6 | ||
|
7 | [XmlAttribute("type")] | |
|
8 | public string TypeName { get; set; } | |
|
9 | ||
|
10 | public abstract void Visit(InjectionParameterBuilder builder); | |
|
11 | } | |
|
12 | } No newline at end of file |
@@ -0,0 +1,17 | |||
|
1 | using System; | |
|
2 | using System.Diagnostics; | |
|
3 | ||
|
4 | namespace Implab.Diagnostics | |
|
5 | { | |
|
6 | public class ChannelAdvertisementEventArgs : EventArgs { | |
|
7 | internal ChannelAdvertisementEventArgs(object channelId, TraceSource source) { | |
|
8 | ChannelId = channelId; | |
|
9 | Source = source; | |
|
10 | } | |
|
11 | ||
|
12 | public object ChannelId { get; private set; } | |
|
13 | ||
|
14 | public TraceSource Source { get; private set; } | |
|
15 | ||
|
16 | } | |
|
17 | } No newline at end of file |
@@ -3,6 +3,17 | |||
|
3 | 3 | <PropertyGroup> |
|
4 | 4 | <TargetFrameworks>netstandard2.0;net46</TargetFrameworks> |
|
5 | 5 | <FrameworkPathOverride Condition="'$(TargetFramework)'=='net46'">/usr/lib/mono/4.6-api/</FrameworkPathOverride> |
|
6 | <Authors>Sergey Smirnov</Authors> | |
|
7 | <Title>Implab.SrviceHost library</Title> | |
|
8 | <Description>Provides simple and flexible XML configuration for the Unity IoC</Description> | |
|
9 | <Copyright>2018 Sergey Smirnov</Copyright> | |
|
10 | <Version>1.0.0</Version> | |
|
11 | <PackageLicenseUrl>https://hg.implab.org/pub/ImplabNet/file/tip/Implab/license.txt</PackageLicenseUrl> | |
|
12 | <PackageProjectUrl>https://implab.org</PackageProjectUrl> | |
|
13 | <RepositoryUrl>https://hg.implab.org/pub/ImplabNet/</RepositoryUrl> | |
|
14 | <RepositoryType>mercurial</RepositoryType> | |
|
15 | <PackageTags>IoC; Unity; Dependency Injection</PackageTags> | |
|
16 | <TargetFrameworks>netstandard2.0;net46</TargetFrameworks> | |
|
6 | 17 | </PropertyGroup> |
|
7 | 18 | |
|
8 | 19 | <ItemGroup> |
@@ -2,7 +2,7 using System.Xml.Serialization; | |||
|
2 | 2 | |
|
3 | 3 | namespace Implab.ServiceHost.Unity |
|
4 | 4 | { |
|
5 |
public class ArrayParameterElement : InjectionParameter |
|
|
5 | public class ArrayParameterElement : AbstractInjectionParameter { | |
|
6 | 6 | |
|
7 | 7 | [XmlAttribute("itemsType")] |
|
8 | 8 | public string ItemsType { get; set; } |
@@ -11,7 +11,7 namespace Implab.ServiceHost.Unity | |||
|
11 | 11 | [XmlElement("value", typeof(ValueParameterElement))] |
|
12 | 12 | [XmlElement("serialized", typeof(SerializedParameterElement))] |
|
13 | 13 | [XmlElement("default", typeof(DefaultParameterElement))] |
|
14 |
public InjectionParameter |
|
|
14 | public AbstractInjectionParameter[] Items { get; set; } | |
|
15 | 15 | |
|
16 | 16 | public override void Visit(InjectionParameterBuilder builder) { |
|
17 | 17 | builder.Visit(this); |
@@ -8,7 +8,7 namespace Implab.ServiceHost.Unity { | |||
|
8 | 8 | [XmlElement("serialized", typeof(SerializedParameterElement))] |
|
9 | 9 | [XmlElement("default", typeof(DefaultParameterElement))] |
|
10 | 10 | [XmlElement("array", typeof(ArrayParameterElement))] |
|
11 |
public InjectionParameter |
|
|
11 | public AbstractInjectionParameter[] Parameters { get; set; } | |
|
12 | 12 | |
|
13 | 13 | public override void Visit(TypeRegistrationBuilder builder) { |
|
14 | 14 | builder.Visit(this); |
@@ -1,6 +1,6 | |||
|
1 | 1 | namespace Implab.ServiceHost.Unity |
|
2 | 2 | { |
|
3 |
public class DefaultParameterElement : InjectionParameter |
|
|
3 | public class DefaultParameterElement : AbstractInjectionParameter { | |
|
4 | 4 | public string Value { |
|
5 | 5 | get { return null; } |
|
6 | 6 | } |
@@ -1,7 +1,7 | |||
|
1 | 1 | using System.Xml.Serialization; |
|
2 | 2 | |
|
3 | 3 | namespace Implab.ServiceHost.Unity { |
|
4 |
public class DependencyParameterElement : InjectionParameter |
|
|
4 | public class DependencyParameterElement : AbstractInjectionParameter { | |
|
5 | 5 | |
|
6 | 6 | [XmlAttribute("name")] |
|
7 | 7 | public string DependencyName { get; set; } |
@@ -36,7 +36,8 namespace Implab.ServiceHost.Unity { | |||
|
36 | 36 | Name = item.RegistrationName, |
|
37 | 37 | RegistrationType = builder.ResolveType(item.RegistrationType), |
|
38 | 38 | FactoryName = Name, |
|
39 | FactoryType = factoryType | |
|
39 | FactoryType = factoryType, | |
|
40 | Lifetime = item.Lifetime.GetLifetime(builder) | |
|
40 | 41 | }; |
|
41 | 42 | builder.Visit(activator); |
|
42 | 43 | } |
@@ -98,7 +98,7 namespace Implab.ServiceHost.Unity { | |||
|
98 | 98 | if (itemsType == null) |
|
99 | 99 | throw new Exception("Failed to determine array elements type"); |
|
100 | 100 | |
|
101 |
InjectionParameterValue[] injections = (arrayParameter.Items ?? new InjectionParameter |
|
|
101 | InjectionParameterValue[] injections = (arrayParameter.Items ?? new AbstractInjectionParameter[0]) | |
|
102 | 102 | .Select(x => { |
|
103 | 103 | var builder = new InjectionParameterBuilder(m_resolver, itemsType); |
|
104 | 104 | x.Visit(builder); |
@@ -11,7 +11,7 namespace Implab.ServiceHost.Unity { | |||
|
11 | 11 | [XmlElement("serialized", typeof(SerializedParameterElement))] |
|
12 | 12 | [XmlElement("default", typeof(DefaultParameterElement))] |
|
13 | 13 | [XmlElement("array", typeof(ArrayParameterElement))] |
|
14 |
public InjectionParameter |
|
|
14 | public AbstractInjectionParameter[] Parameters { get; set; } | |
|
15 | 15 | |
|
16 | 16 | public override void Visit(TypeRegistrationBuilder context) { |
|
17 | 17 | context.Visit(this); |
@@ -11,7 +11,7 namespace Implab.ServiceHost.Unity { | |||
|
11 | 11 | [XmlElement("serialized", typeof(SerializedParameterElement))] |
|
12 | 12 | [XmlElement("default", typeof(DefaultParameterElement))] |
|
13 | 13 | [XmlElement("array", typeof(ArrayParameterElement))] |
|
14 |
public InjectionParameter |
|
|
14 | public AbstractInjectionParameter Value { get; set; } | |
|
15 | 15 | |
|
16 | 16 | public override void Visit(TypeRegistrationBuilder context) { |
|
17 | 17 | context.Visit(this); |
@@ -7,5 +7,11 namespace Implab.ServiceHost.Unity { | |||
|
7 | 7 | |
|
8 | 8 | [XmlAttribute("name")] |
|
9 | 9 | public string RegistrationName { get; set; } |
|
10 | ||
|
11 | [XmlElement("signleton", typeof(SingletonLifetimeElement))] | |
|
12 | [XmlElement("context", typeof(ContextLifetimeElement))] | |
|
13 | [XmlElement("container", typeof(ContainerLifetimeElement))] | |
|
14 | [XmlElement("hierarchy", typeof(HierarchicalLifetimeElement))] | |
|
15 | public LifetimeElement Lifetime {get; set;} | |
|
10 | 16 | } |
|
11 | 17 | } No newline at end of file |
@@ -5,7 +5,7 using System.Xml.Serialization; | |||
|
5 | 5 | |
|
6 | 6 | namespace Implab.ServiceHost.Unity |
|
7 | 7 | { |
|
8 |
public class SerializedParameterElement : InjectionParameter |
|
|
8 | public class SerializedParameterElement : AbstractInjectionParameter { | |
|
9 | 9 | [XmlAttribute("href")] |
|
10 | 10 | public string Location { get; set; } |
|
11 | 11 |
@@ -2,7 +2,7 using System.ComponentModel; | |||
|
2 | 2 | using System.Xml.Serialization; |
|
3 | 3 | |
|
4 | 4 | namespace Implab.ServiceHost.Unity { |
|
5 |
public class ValueParameterElement : InjectionParameter |
|
|
5 | public class ValueParameterElement : AbstractInjectionParameter { | |
|
6 | 6 | [XmlAttribute("value")] |
|
7 | 7 | public string Value { get; set; } |
|
8 | 8 |
@@ -1,51 +1,64 | |||
|
1 | 1 | # XML Конфигурация IoC контейнера |
|
2 | 2 | |
|
3 |
|
|
|
3 | Библиоетка создавалась для загрузки и применения конфигурации к IoC контейнеру, она не предназначена для конфигурирования | |
|
4 | 4 | контейнера во время выполнения, большинство контейнеров уже обладают данным функционалом. |
|
5 | 5 | |
|
6 | 6 | На данный момент поддерживается единственный вид контейнера - [Unity Container](https://unitycontainer.github.io/) |
|
7 | 7 | |
|
8 | Unity уже обладает средствами загрузки конфигурации из XML, данная библиотека позволяет решать следующие задачи | |
|
8 | Unity уже обладает средствами загрузки конфигурации из XML, данная библиотека реализует аналогичный функционал, кроме того, позволяет решать следующие задачи: | |
|
9 | 9 | |
|
10 | 10 | - Конфигурация является простым Xml документом, который можно получить из любого источика и не ограничивается `.config` файлами приложения |
|
11 | 11 | - Включение существующе конфигурации `<include href='config.xml'/>` в текущую |
|
12 | 12 | - Поддержка сериализованных объектов в качестве регистраций сервисов и параметров |
|
13 | - Описание зависимостей может быть расширено собсвтенными элементами с произвольной структурой | |
|
14 | - Поддержка специфиакции генериков любой вложенности `Dictionary{Foo,Bar{Int32}}` | |
|
13 | - Поддержка специфиакции генериков любой вложенности, например `Dictionary{Foo,Bar{Int32}}` | |
|
14 | - Поддержка фабрик в XML конфигурации | |
|
15 | - Расширение схемы XML конфигурации собственными элементами | |
|
15 | 16 | |
|
16 | 17 | ## Общая архитектура |
|
17 | 18 | |
|
18 |
`Implab.ServiceHost.Unity` содержит в себе классы для загрузки и применения XML конфигурации к IoC контейнеру |
|
|
19 | Пространство имен `Implab.ServiceHost.Unity` содержит в себе классы для загрузки и применения XML конфигурации к IoC контейнеру. | |
|
20 | ||
|
21 | Применение конфигурации к контейнеру состоит из следующих основных шагов: | |
|
19 | 22 | |
|
20 | 1. Настраивается схема `ContainerConfigurationSchema` | |
|
23 | 1. Настраивается схема `ContainerConfigurationSchema` XML конфигурации контейнера | |
|
21 | 24 | 2. Загружается документ и десереализуется в виде `ContainerElement` |
|
22 | 3. Создается `ContainerBuilder` при помощи которого применяются настройки из `ContainerElement` | |
|
25 | 3. Создается `ContainerBuilder` при помощи которого применяются настройки из `ContainerElement` к контейнеру | |
|
23 | 26 | |
|
24 |
`ContainerConfigurationSchema` |
|
|
27 | Схема `ContainerConfigurationSchema` определяет элементы документа, которые могут быть использованы в конфигурации контейнера, позволяет создать `XmlSerializer`, который используется для загрузки конфигурации. | |
|
25 | 28 | |
|
26 | `ContainerBuilder` - основной класс, который используется для применения конфигурации к контейнеру, добавляет записи регистрации сервисов. | |
|
29 | `ContainerBuilder` - основной класс, который используется для применения конфигурации к контейнеру, он добавляет записи регистрации сервисов из конфигурации в контейнер. | |
|
27 | 30 | |
|
28 | `ContainerElement` - Корневой элемент конфигурации, который загружается из документа. | |
|
31 | `ContainerElement` - Конфигурация контейнера, которая загружается из документа, состоит из директив для `ContainerBuilder`, а также из записей регистрации сервисов. | |
|
29 | 32 | |
|
30 | Классы заканчивающиеся словом `Builder` используются для применения конфигурации к контейнеру, | |
|
31 | классы заканчивающиеся на `Element` содержат информацию о конфигурации и десериализуются из исходного документа. | |
|
33 | В библиотеки приняты следующие правила именования классов: | |
|
34 | ||
|
35 | - `***Builder` используются для применения конфигурации к контейнеру, | |
|
36 | - `***Element` содержат информацию о конфигурации и десериализуются из исходного документа. | |
|
32 | 37 | |
|
33 | 38 | ## Структура конфигурации контейнера |
|
34 | 39 | |
|
35 |
Элемент верхнего уровня всегда ` |
|
|
40 | Элемент верхнего уровня всегда `container`, он используется для хранения набора элеметов, которые распознаются и выполняются `ContainerBuilder`. | |
|
36 | 41 | |
|
37 | 42 | Все элементы, входящие в контейнер наследуются от абстрактного класса `ContainerItemElement`, |
|
38 | 43 | который позволяет получить текущий `ContainerBuilder` и выполнить над ним какие-либо действия. |
|
39 | 44 | |
|
40 | Примерами элементов контейнера могут быть | |
|
45 | Основные элементы конфигурации контенейра | |
|
41 | 46 | |
|
42 | 47 | - `<include href='config.xml'/>` - включение конфигурации из указанного места |
|
43 | 48 | - `<namespace name='My.App'/>` - добавление пространства имен для поиска типов |
|
44 | 49 | - `<register type='MyGenericType{}'/>` - добавление в контейнер регистрации типа ``My.App.MyGenericType`1`` |
|
50 | - `<factory type='IFactory{Foo}' mapTo ='MyFactory'/>` - фабрика, регистрирует свой тип, а также тип `Foo` | |
|
51 | - `<serialized />` - сериализованный экземпляр объекта, использует `XmlSerializer` для десериализации | |
|
52 | - `<value />` - значение объекта в виде строки, используется для простых типов | |
|
45 | 53 | |
|
46 | 54 | Полный набор элементов, доступных для использования в контейнере определяет схема `ContainerConfigurationSchema`, |
|
47 | 55 | разработчик может расширить контейнер совими собственными элементами зарегистрировав их в схеме. |
|
48 | 56 | |
|
57 | ### register | |
|
58 | ||
|
59 | О | |
|
60 | ||
|
61 | ||
|
49 | 62 | Например, мы используем компоненту `MyHttpClient` для загрузки данных |
|
50 | 63 | |
|
51 | 64 | ```xml |
@@ -1,4 +1,7 | |||
|
1 | using System; | |
|
1 | // enable System.Diagnostics trace methods | |
|
2 | #define TRACE | |
|
3 | ||
|
4 | using System; | |
|
2 | 5 | using System.Collections.Generic; |
|
3 | 6 | using System.Diagnostics; |
|
4 | 7 | using System.Linq; |
@@ -9,7 +12,21 using System.Threading.Tasks; | |||
|
9 | 12 | namespace Implab.Diagnostics { |
|
10 | 13 | public static class Trace<T> { |
|
11 | 14 | |
|
12 | public static TraceSource TraceSource { get; } = new TraceSource(typeof(T).Name); | |
|
15 | static Lazy<TraceSource> _traceSource = new Lazy<TraceSource>(CreateChannel, LazyThreadSafetyMode.ExecutionAndPublication); | |
|
16 | ||
|
17 | static int _nextId; | |
|
18 | ||
|
19 | static TraceSource CreateChannel() { | |
|
20 | var id = Interlocked.Increment(ref _nextId); | |
|
21 | return new TraceSource(typeof(T).Name); | |
|
22 | } | |
|
23 | ||
|
24 | public static TraceSource TraceSource { get { return _traceSource.Value; } } | |
|
25 | ||
|
26 | public static IDisposable Subscribe() { | |
|
27 | ||
|
28 | throw new NotImplementedException(); | |
|
29 | } | |
|
13 | 30 | |
|
14 | 31 | #if NETFX_TRACE_BUG |
|
15 | 32 | readonly static AsyncLocal<object> m_currentOperation = new AsyncLocal<object>(); |
@@ -8,7 +8,7 | |||
|
8 | 8 | and SharedLock, Trace helpers on top of System.Diagnostics, ObjectPool etc. |
|
9 | 9 | </Description> |
|
10 | 10 | <Copyright>2012-2018 Sergey Smirnov</Copyright> |
|
11 |
<Version>3.0.1 |
|
|
11 | <Version>3.0.12</Version> | |
|
12 | 12 | <PackageLicenseUrl>https://hg.implab.org/pub/ImplabNet/file/tip/Implab/license.txt</PackageLicenseUrl> |
|
13 | 13 | <PackageProjectUrl>https://implab.org</PackageProjectUrl> |
|
14 | 14 | <RepositoryUrl>https://hg.implab.org/pub/ImplabNet/</RepositoryUrl> |
|
1 | NO CONTENT: file was removed |
|
1 | NO CONTENT: file was removed |
General Comments 3
ok, latest stable version should be in default
You need to be logged in to leave comments.
Login now