##// END OF EJS Templates
pool refactoring
cin -
r117:8beee0d11de6 v2
parent child
Show More
@@ -0,0 +1,90
1 using System;
2 using Implab.Parallels;
3 using System.Threading;
4 using System.Diagnostics;
5 using System.Diagnostics.CodeAnalysis;
6
7 namespace Implab {
8 public abstract class DisposablePool<T> : IDisposable {
9 readonly int m_size;
10 readonly MTQueue<T> m_queue = new MTQueue<T>();
11
12 [SuppressMessage("Microsoft.Design", "CA1000:DoNotDeclareStaticMembersOnGenericTypes")]
13 static readonly bool _isValueType = typeof(T).IsValueType;
14
15 bool m_disposed;
16
17 int m_count;
18
19 protected DisposablePool(int size) {
20 m_size = size;
21 }
22
23 protected DisposablePool() : this(Environment.ProcessorCount+1) {
24 }
25
26 public T Allocate() {
27 if (m_disposed)
28 throw new ObjectDisposedException(ToString());
29
30 T instance;
31 if (m_queue.TryDequeue(out instance)) {
32 Interlocked.Decrement(ref m_count);
33 } else {
34 instance = CreateInstance();
35 Debug.Assert(!Object.Equals(instance, default(T)) || _isValueType);
36 }
37 return instance;
38 }
39
40 protected abstract T CreateInstance();
41
42 protected virtual void CleanupInstance(T instance) {
43 }
44
45 public void Release(T instance) {
46 if ( Object.Equals(instance,default(T)) && !_isValueType)
47 return;
48
49 Thread.MemoryBarrier();
50 if (m_count < m_size && !m_disposed) {
51 Interlocked.Increment(ref m_count);
52
53 CleanupInstance(instance);
54
55 m_queue.Enqueue(instance);
56
57 // пока элемент возвращался в кеш, была начата операция освобождения всего кеша
58 // и возможно уже законцена, в таком случае следует извлечь элемент обратно и
59 // освободить его. Если операция освобождения кеша еще не заврешилась, то будет
60 // изъят и освобожден произвольный элемен, что не повлияет на ход всего процесса.
61 if (m_disposed && m_queue.TryDequeue(out instance) && instance is IDisposable)
62 ((IDisposable)instance).Dispose() ;
63
64 } else {
65 if (instance is IDisposable)
66 ((IDisposable)instance).Dispose();
67 }
68 }
69
70 protected virtual void Dispose(bool disposing) {
71 if (disposing) {
72 m_disposed = true;
73 T instance;
74 while (m_queue.TryDequeue(out instance))
75 if (instance is IDisposable)
76 ((IDisposable)instance).Dispose();
77 }
78 }
79
80 #region IDisposable implementation
81
82 public void Dispose() {
83 Dispose(true);
84 GC.SuppressFinalize(this);
85 }
86
87 #endregion
88 }
89 }
90
@@ -1,225 +1,225
1 <?xml version="1.0" encoding="utf-8"?>
1 <?xml version="1.0" encoding="utf-8"?>
2 <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
2 <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3 <PropertyGroup>
3 <PropertyGroup>
4 <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
4 <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
5 <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
5 <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
6 <ProjectGuid>{F550F1F8-8746-4AD0-9614-855F4C4B7F05}</ProjectGuid>
6 <ProjectGuid>{F550F1F8-8746-4AD0-9614-855F4C4B7F05}</ProjectGuid>
7 <OutputType>Library</OutputType>
7 <OutputType>Library</OutputType>
8 <RootNamespace>Implab</RootNamespace>
8 <RootNamespace>Implab</RootNamespace>
9 <AssemblyName>Implab</AssemblyName>
9 <AssemblyName>Implab</AssemblyName>
10 </PropertyGroup>
10 </PropertyGroup>
11 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
11 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
12 <DebugSymbols>true</DebugSymbols>
12 <DebugSymbols>true</DebugSymbols>
13 <DebugType>full</DebugType>
13 <DebugType>full</DebugType>
14 <Optimize>false</Optimize>
14 <Optimize>false</Optimize>
15 <OutputPath>bin\Debug</OutputPath>
15 <OutputPath>bin\Debug</OutputPath>
16 <DefineConstants>TRACE;DEBUG;</DefineConstants>
16 <DefineConstants>TRACE;DEBUG;</DefineConstants>
17 <ErrorReport>prompt</ErrorReport>
17 <ErrorReport>prompt</ErrorReport>
18 <WarningLevel>4</WarningLevel>
18 <WarningLevel>4</WarningLevel>
19 <ConsolePause>false</ConsolePause>
19 <ConsolePause>false</ConsolePause>
20 <RunCodeAnalysis>true</RunCodeAnalysis>
20 <RunCodeAnalysis>true</RunCodeAnalysis>
21 </PropertyGroup>
21 </PropertyGroup>
22 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
22 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
23 <DebugType>full</DebugType>
23 <DebugType>full</DebugType>
24 <Optimize>true</Optimize>
24 <Optimize>true</Optimize>
25 <OutputPath>bin\Release</OutputPath>
25 <OutputPath>bin\Release</OutputPath>
26 <ErrorReport>prompt</ErrorReport>
26 <ErrorReport>prompt</ErrorReport>
27 <WarningLevel>4</WarningLevel>
27 <WarningLevel>4</WarningLevel>
28 <ConsolePause>false</ConsolePause>
28 <ConsolePause>false</ConsolePause>
29 </PropertyGroup>
29 </PropertyGroup>
30 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug 4.5|AnyCPU' ">
30 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug 4.5|AnyCPU' ">
31 <DebugSymbols>true</DebugSymbols>
31 <DebugSymbols>true</DebugSymbols>
32 <DebugType>full</DebugType>
32 <DebugType>full</DebugType>
33 <Optimize>false</Optimize>
33 <Optimize>false</Optimize>
34 <OutputPath>bin\Debug</OutputPath>
34 <OutputPath>bin\Debug</OutputPath>
35 <DefineConstants>TRACE;DEBUG;NET_4_5</DefineConstants>
35 <DefineConstants>TRACE;DEBUG;NET_4_5</DefineConstants>
36 <ErrorReport>prompt</ErrorReport>
36 <ErrorReport>prompt</ErrorReport>
37 <WarningLevel>4</WarningLevel>
37 <WarningLevel>4</WarningLevel>
38 <RunCodeAnalysis>true</RunCodeAnalysis>
38 <RunCodeAnalysis>true</RunCodeAnalysis>
39 <ConsolePause>false</ConsolePause>
39 <ConsolePause>false</ConsolePause>
40 </PropertyGroup>
40 </PropertyGroup>
41 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release 4.5|AnyCPU' ">
41 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release 4.5|AnyCPU' ">
42 <Optimize>true</Optimize>
42 <Optimize>true</Optimize>
43 <OutputPath>bin\Release</OutputPath>
43 <OutputPath>bin\Release</OutputPath>
44 <ErrorReport>prompt</ErrorReport>
44 <ErrorReport>prompt</ErrorReport>
45 <WarningLevel>4</WarningLevel>
45 <WarningLevel>4</WarningLevel>
46 <ConsolePause>false</ConsolePause>
46 <ConsolePause>false</ConsolePause>
47 <DefineConstants>NET_4_5</DefineConstants>
47 <DefineConstants>NET_4_5</DefineConstants>
48 </PropertyGroup>
48 </PropertyGroup>
49 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'DebugMono|AnyCPU' ">
49 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'DebugMono|AnyCPU' ">
50 <DebugSymbols>true</DebugSymbols>
50 <DebugSymbols>true</DebugSymbols>
51 <DebugType>full</DebugType>
51 <DebugType>full</DebugType>
52 <Optimize>false</Optimize>
52 <Optimize>false</Optimize>
53 <OutputPath>bin\Debug</OutputPath>
53 <OutputPath>bin\Debug</OutputPath>
54 <DefineConstants>TRACE;DEBUG;NET_4_5;MONO</DefineConstants>
54 <DefineConstants>TRACE;DEBUG;NET_4_5;MONO</DefineConstants>
55 <ErrorReport>prompt</ErrorReport>
55 <ErrorReport>prompt</ErrorReport>
56 <WarningLevel>4</WarningLevel>
56 <WarningLevel>4</WarningLevel>
57 <RunCodeAnalysis>true</RunCodeAnalysis>
57 <RunCodeAnalysis>true</RunCodeAnalysis>
58 <ConsolePause>false</ConsolePause>
58 <ConsolePause>false</ConsolePause>
59 </PropertyGroup>
59 </PropertyGroup>
60 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'ReleaseMono|AnyCPU' ">
60 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'ReleaseMono|AnyCPU' ">
61 <Optimize>true</Optimize>
61 <Optimize>true</Optimize>
62 <OutputPath>bin\Release</OutputPath>
62 <OutputPath>bin\Release</OutputPath>
63 <DefineConstants>NET_4_5;MONO;</DefineConstants>
63 <DefineConstants>NET_4_5;MONO;</DefineConstants>
64 <ErrorReport>prompt</ErrorReport>
64 <ErrorReport>prompt</ErrorReport>
65 <WarningLevel>4</WarningLevel>
65 <WarningLevel>4</WarningLevel>
66 <ConsolePause>false</ConsolePause>
66 <ConsolePause>false</ConsolePause>
67 </PropertyGroup>
67 </PropertyGroup>
68 <ItemGroup>
68 <ItemGroup>
69 <Reference Include="System" />
69 <Reference Include="System" />
70 <Reference Include="System.Xml" />
70 <Reference Include="System.Xml" />
71 </ItemGroup>
71 </ItemGroup>
72 <ItemGroup>
72 <ItemGroup>
73 <Compile Include="Component.cs" />
73 <Compile Include="Component.cs" />
74 <Compile Include="CustomEqualityComparer.cs" />
74 <Compile Include="CustomEqualityComparer.cs" />
75 <Compile Include="Diagnostics\ConsoleTraceListener.cs" />
75 <Compile Include="Diagnostics\ConsoleTraceListener.cs" />
76 <Compile Include="Diagnostics\EventText.cs" />
76 <Compile Include="Diagnostics\EventText.cs" />
77 <Compile Include="Diagnostics\IEventTextFormatter.cs" />
77 <Compile Include="Diagnostics\IEventTextFormatter.cs" />
78 <Compile Include="Diagnostics\LogChannel.cs" />
78 <Compile Include="Diagnostics\LogChannel.cs" />
79 <Compile Include="Diagnostics\LogicalOperation.cs" />
79 <Compile Include="Diagnostics\LogicalOperation.cs" />
80 <Compile Include="Diagnostics\TextFileListener.cs" />
80 <Compile Include="Diagnostics\TextFileListener.cs" />
81 <Compile Include="Diagnostics\TextListenerBase.cs" />
81 <Compile Include="Diagnostics\TextListenerBase.cs" />
82 <Compile Include="Diagnostics\TraceLog.cs" />
82 <Compile Include="Diagnostics\TraceLog.cs" />
83 <Compile Include="Diagnostics\TraceEvent.cs" />
83 <Compile Include="Diagnostics\TraceEvent.cs" />
84 <Compile Include="Diagnostics\TraceEventType.cs" />
84 <Compile Include="Diagnostics\TraceEventType.cs" />
85 <Compile Include="Disposable.cs" />
85 <Compile Include="Disposable.cs" />
86 <Compile Include="ICancellable.cs" />
86 <Compile Include="ICancellable.cs" />
87 <Compile Include="IProgressHandler.cs" />
87 <Compile Include="IProgressHandler.cs" />
88 <Compile Include="IProgressNotifier.cs" />
88 <Compile Include="IProgressNotifier.cs" />
89 <Compile Include="IPromiseT.cs" />
89 <Compile Include="IPromiseT.cs" />
90 <Compile Include="IPromise.cs" />
90 <Compile Include="IPromise.cs" />
91 <Compile Include="IServiceLocator.cs" />
91 <Compile Include="IServiceLocator.cs" />
92 <Compile Include="ITaskController.cs" />
92 <Compile Include="ITaskController.cs" />
93 <Compile Include="JSON\JSONElementContext.cs" />
93 <Compile Include="JSON\JSONElementContext.cs" />
94 <Compile Include="JSON\JSONElementType.cs" />
94 <Compile Include="JSON\JSONElementType.cs" />
95 <Compile Include="JSON\JSONGrammar.cs" />
95 <Compile Include="JSON\JSONGrammar.cs" />
96 <Compile Include="JSON\JSONParser.cs" />
96 <Compile Include="JSON\JSONParser.cs" />
97 <Compile Include="JSON\JSONScanner.cs" />
97 <Compile Include="JSON\JSONScanner.cs" />
98 <Compile Include="JSON\JsonTokenType.cs" />
98 <Compile Include="JSON\JsonTokenType.cs" />
99 <Compile Include="JSON\JSONWriter.cs" />
99 <Compile Include="JSON\JSONWriter.cs" />
100 <Compile Include="JSON\JSONXmlReader.cs" />
100 <Compile Include="JSON\JSONXmlReader.cs" />
101 <Compile Include="JSON\JSONXmlReaderOptions.cs" />
101 <Compile Include="JSON\JSONXmlReaderOptions.cs" />
102 <Compile Include="JSON\StringTranslator.cs" />
102 <Compile Include="JSON\StringTranslator.cs" />
103 <Compile Include="Parallels\DispatchPool.cs" />
103 <Compile Include="Parallels\DispatchPool.cs" />
104 <Compile Include="Parallels\ArrayTraits.cs" />
104 <Compile Include="Parallels\ArrayTraits.cs" />
105 <Compile Include="Parallels\MTQueue.cs" />
105 <Compile Include="Parallels\MTQueue.cs" />
106 <Compile Include="Parallels\WorkerPool.cs" />
106 <Compile Include="Parallels\WorkerPool.cs" />
107 <Compile Include="Parsing\Alphabet.cs" />
107 <Compile Include="Parsing\Alphabet.cs" />
108 <Compile Include="Parsing\AlphabetBase.cs" />
108 <Compile Include="Parsing\AlphabetBase.cs" />
109 <Compile Include="Parsing\AltToken.cs" />
109 <Compile Include="Parsing\AltToken.cs" />
110 <Compile Include="Parsing\BinaryToken.cs" />
110 <Compile Include="Parsing\BinaryToken.cs" />
111 <Compile Include="Parsing\CatToken.cs" />
111 <Compile Include="Parsing\CatToken.cs" />
112 <Compile Include="Parsing\CDFADefinition.cs" />
112 <Compile Include="Parsing\CDFADefinition.cs" />
113 <Compile Include="Parsing\DFABuilder.cs" />
113 <Compile Include="Parsing\DFABuilder.cs" />
114 <Compile Include="Parsing\DFADefinitionBase.cs" />
114 <Compile Include="Parsing\DFADefinitionBase.cs" />
115 <Compile Include="Parsing\DFAStateDescriptor.cs" />
115 <Compile Include="Parsing\DFAStateDescriptor.cs" />
116 <Compile Include="Parsing\DFAutomaton.cs" />
116 <Compile Include="Parsing\DFAutomaton.cs" />
117 <Compile Include="Parsing\EDFADefinition.cs" />
117 <Compile Include="Parsing\EDFADefinition.cs" />
118 <Compile Include="Parsing\EmptyToken.cs" />
118 <Compile Include="Parsing\EmptyToken.cs" />
119 <Compile Include="Parsing\EndToken.cs" />
119 <Compile Include="Parsing\EndToken.cs" />
120 <Compile Include="Parsing\EnumAlphabet.cs" />
120 <Compile Include="Parsing\EnumAlphabet.cs" />
121 <Compile Include="Parsing\Grammar.cs" />
121 <Compile Include="Parsing\Grammar.cs" />
122 <Compile Include="Parsing\IAlphabet.cs" />
122 <Compile Include="Parsing\IAlphabet.cs" />
123 <Compile Include="Parsing\IDFADefinition.cs" />
123 <Compile Include="Parsing\IDFADefinition.cs" />
124 <Compile Include="Parsing\IVisitor.cs" />
124 <Compile Include="Parsing\IVisitor.cs" />
125 <Compile Include="Parsing\ParserException.cs" />
125 <Compile Include="Parsing\ParserException.cs" />
126 <Compile Include="Parsing\Scanner.cs" />
126 <Compile Include="Parsing\Scanner.cs" />
127 <Compile Include="Parsing\StarToken.cs" />
127 <Compile Include="Parsing\StarToken.cs" />
128 <Compile Include="Parsing\SymbolToken.cs" />
128 <Compile Include="Parsing\SymbolToken.cs" />
129 <Compile Include="Parsing\Token.cs" />
129 <Compile Include="Parsing\Token.cs" />
130 <Compile Include="SafePool.cs" />
131 <Compile Include="ServiceLocator.cs" />
130 <Compile Include="ServiceLocator.cs" />
132 <Compile Include="TaskController.cs" />
131 <Compile Include="TaskController.cs" />
133 <Compile Include="ProgressInitEventArgs.cs" />
132 <Compile Include="ProgressInitEventArgs.cs" />
134 <Compile Include="Properties\AssemblyInfo.cs" />
133 <Compile Include="Properties\AssemblyInfo.cs" />
135 <Compile Include="Promise.cs" />
134 <Compile Include="Promise.cs" />
136 <Compile Include="Parallels\AsyncPool.cs" />
135 <Compile Include="Parallels\AsyncPool.cs" />
137 <Compile Include="Safe.cs" />
136 <Compile Include="Safe.cs" />
138 <Compile Include="ValueEventArgs.cs" />
137 <Compile Include="ValueEventArgs.cs" />
139 <Compile Include="PromiseExtensions.cs" />
138 <Compile Include="PromiseExtensions.cs" />
140 <Compile Include="TransientPromiseException.cs" />
139 <Compile Include="TransientPromiseException.cs" />
141 <Compile Include="SyncContextPromise.cs" />
140 <Compile Include="SyncContextPromise.cs" />
142 <Compile Include="ObjectPool.cs" />
143 <Compile Include="Diagnostics\OperationContext.cs" />
141 <Compile Include="Diagnostics\OperationContext.cs" />
144 <Compile Include="Diagnostics\TraceContext.cs" />
142 <Compile Include="Diagnostics\TraceContext.cs" />
145 <Compile Include="Diagnostics\LogEventArgs.cs" />
143 <Compile Include="Diagnostics\LogEventArgs.cs" />
146 <Compile Include="Diagnostics\LogEventArgsT.cs" />
144 <Compile Include="Diagnostics\LogEventArgsT.cs" />
147 <Compile Include="Diagnostics\Extensions.cs" />
145 <Compile Include="Diagnostics\Extensions.cs" />
148 <Compile Include="IComponentContainer.cs" />
146 <Compile Include="IComponentContainer.cs" />
149 <Compile Include="PromiseEventType.cs" />
147 <Compile Include="PromiseEventType.cs" />
150 <Compile Include="Parallels\MTCustomQueue.cs" />
148 <Compile Include="Parallels\MTCustomQueue.cs" />
151 <Compile Include="Parallels\MTCustomQueueNode.cs" />
149 <Compile Include="Parallels\MTCustomQueueNode.cs" />
152 <Compile Include="ComponentContainer.cs" />
150 <Compile Include="ComponentContainer.cs" />
151 <Compile Include="DisposablePool.cs" />
152 <Compile Include="ObjectPool.cs" />
153 </ItemGroup>
153 </ItemGroup>
154 <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
154 <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
155 <ItemGroup />
155 <ItemGroup />
156 <ProjectExtensions>
156 <ProjectExtensions>
157 <MonoDevelop>
157 <MonoDevelop>
158 <Properties>
158 <Properties>
159 <Policies>
159 <Policies>
160 <CSharpFormattingPolicy IndentSwitchBody="True" NamespaceBraceStyle="EndOfLine" ClassBraceStyle="EndOfLine" InterfaceBraceStyle="EndOfLine" StructBraceStyle="EndOfLine" EnumBraceStyle="EndOfLine" MethodBraceStyle="EndOfLine" ConstructorBraceStyle="EndOfLine" DestructorBraceStyle="EndOfLine" BeforeMethodDeclarationParentheses="False" BeforeMethodCallParentheses="False" BeforeConstructorDeclarationParentheses="False" NewLineBeforeConstructorInitializerColon="NewLine" NewLineAfterConstructorInitializerColon="SameLine" BeforeIndexerDeclarationBracket="False" BeforeDelegateDeclarationParentheses="False" NewParentheses="False" SpacesBeforeBrackets="False" inheritsSet="Mono" inheritsScope="text/x-csharp" scope="text/x-csharp" />
160 <CSharpFormattingPolicy IndentSwitchBody="True" NamespaceBraceStyle="EndOfLine" ClassBraceStyle="EndOfLine" InterfaceBraceStyle="EndOfLine" StructBraceStyle="EndOfLine" EnumBraceStyle="EndOfLine" MethodBraceStyle="EndOfLine" ConstructorBraceStyle="EndOfLine" DestructorBraceStyle="EndOfLine" BeforeMethodDeclarationParentheses="False" BeforeMethodCallParentheses="False" BeforeConstructorDeclarationParentheses="False" NewLineBeforeConstructorInitializerColon="NewLine" NewLineAfterConstructorInitializerColon="SameLine" BeforeIndexerDeclarationBracket="False" BeforeDelegateDeclarationParentheses="False" NewParentheses="False" SpacesBeforeBrackets="False" inheritsSet="Mono" inheritsScope="text/x-csharp" scope="text/x-csharp" />
161 <TextStylePolicy FileWidth="120" EolMarker="Unix" inheritsSet="VisualStudio" inheritsScope="text/plain" scope="text/x-csharp" />
161 <TextStylePolicy FileWidth="120" EolMarker="Unix" inheritsSet="VisualStudio" inheritsScope="text/plain" scope="text/x-csharp" />
162 <DotNetNamingPolicy DirectoryNamespaceAssociation="PrefixedHierarchical" ResourceNamePolicy="MSBuild" />
162 <DotNetNamingPolicy DirectoryNamespaceAssociation="PrefixedHierarchical" ResourceNamePolicy="MSBuild" />
163 <TextStylePolicy FileWidth="120" TabsToSpaces="False" inheritsSet="VisualStudio" inheritsScope="text/plain" scope="application/xml" />
163 <TextStylePolicy FileWidth="120" TabsToSpaces="False" inheritsSet="VisualStudio" inheritsScope="text/plain" scope="application/xml" />
164 <XmlFormattingPolicy inheritsSet="Mono" inheritsScope="application/xml" scope="application/xml" />
164 <XmlFormattingPolicy inheritsSet="Mono" inheritsScope="application/xml" scope="application/xml" />
165 <TextStylePolicy FileWidth="120" TabsToSpaces="False" inheritsSet="VisualStudio" inheritsScope="text/plain" scope="text/plain" />
165 <TextStylePolicy FileWidth="120" TabsToSpaces="False" inheritsSet="VisualStudio" inheritsScope="text/plain" scope="text/plain" />
166 <NameConventionPolicy>
166 <NameConventionPolicy>
167 <Rules>
167 <Rules>
168 <NamingRule Name="Namespaces" AffectedEntity="Namespace" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
168 <NamingRule Name="Namespaces" AffectedEntity="Namespace" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
169 <NamingRule Name="Types" AffectedEntity="Class, Struct, Enum, Delegate" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
169 <NamingRule Name="Types" AffectedEntity="Class, Struct, Enum, Delegate" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
170 <NamingRule Name="Interfaces" AffectedEntity="Interface" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
170 <NamingRule Name="Interfaces" AffectedEntity="Interface" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
171 <RequiredPrefixes>
171 <RequiredPrefixes>
172 <String>I</String>
172 <String>I</String>
173 </RequiredPrefixes>
173 </RequiredPrefixes>
174 </NamingRule>
174 </NamingRule>
175 <NamingRule Name="Attributes" AffectedEntity="CustomAttributes" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
175 <NamingRule Name="Attributes" AffectedEntity="CustomAttributes" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
176 <RequiredSuffixes>
176 <RequiredSuffixes>
177 <String>Attribute</String>
177 <String>Attribute</String>
178 </RequiredSuffixes>
178 </RequiredSuffixes>
179 </NamingRule>
179 </NamingRule>
180 <NamingRule Name="Event Arguments" AffectedEntity="CustomEventArgs" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
180 <NamingRule Name="Event Arguments" AffectedEntity="CustomEventArgs" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
181 <RequiredSuffixes>
181 <RequiredSuffixes>
182 <String>EventArgs</String>
182 <String>EventArgs</String>
183 </RequiredSuffixes>
183 </RequiredSuffixes>
184 </NamingRule>
184 </NamingRule>
185 <NamingRule Name="Exceptions" AffectedEntity="CustomExceptions" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
185 <NamingRule Name="Exceptions" AffectedEntity="CustomExceptions" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
186 <RequiredSuffixes>
186 <RequiredSuffixes>
187 <String>Exception</String>
187 <String>Exception</String>
188 </RequiredSuffixes>
188 </RequiredSuffixes>
189 </NamingRule>
189 </NamingRule>
190 <NamingRule Name="Methods" AffectedEntity="Methods" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
190 <NamingRule Name="Methods" AffectedEntity="Methods" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
191 <NamingRule Name="Static Readonly Fields" AffectedEntity="ReadonlyField" VisibilityMask="Internal, Protected, Public" NamingStyle="CamelCase" IncludeInstanceMembers="False" IncludeStaticEntities="True" />
191 <NamingRule Name="Static Readonly Fields" AffectedEntity="ReadonlyField" VisibilityMask="Internal, Protected, Public" NamingStyle="CamelCase" IncludeInstanceMembers="False" IncludeStaticEntities="True" />
192 <NamingRule Name="Fields (Non Private)" AffectedEntity="Field" VisibilityMask="Internal, Public" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
192 <NamingRule Name="Fields (Non Private)" AffectedEntity="Field" VisibilityMask="Internal, Public" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
193 <NamingRule Name="ReadOnly Fields (Non Private)" AffectedEntity="ReadonlyField" VisibilityMask="Internal, Public" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="False" />
193 <NamingRule Name="ReadOnly Fields (Non Private)" AffectedEntity="ReadonlyField" VisibilityMask="Internal, Public" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="False" />
194 <NamingRule Name="Fields (Private)" AffectedEntity="Field, ReadonlyField" VisibilityMask="Private, Protected" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="False">
194 <NamingRule Name="Fields (Private)" AffectedEntity="Field, ReadonlyField" VisibilityMask="Private, Protected" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="False">
195 <RequiredPrefixes>
195 <RequiredPrefixes>
196 <String>m_</String>
196 <String>m_</String>
197 </RequiredPrefixes>
197 </RequiredPrefixes>
198 </NamingRule>
198 </NamingRule>
199 <NamingRule Name="Static Fields (Private)" AffectedEntity="Field" VisibilityMask="Private" NamingStyle="CamelCase" IncludeInstanceMembers="False" IncludeStaticEntities="True">
199 <NamingRule Name="Static Fields (Private)" AffectedEntity="Field" VisibilityMask="Private" NamingStyle="CamelCase" IncludeInstanceMembers="False" IncludeStaticEntities="True">
200 <RequiredPrefixes>
200 <RequiredPrefixes>
201 <String>_</String>
201 <String>_</String>
202 </RequiredPrefixes>
202 </RequiredPrefixes>
203 </NamingRule>
203 </NamingRule>
204 <NamingRule Name="ReadOnly Fields (Private)" AffectedEntity="ReadonlyField" VisibilityMask="Private, Protected" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="False">
204 <NamingRule Name="ReadOnly Fields (Private)" AffectedEntity="ReadonlyField" VisibilityMask="Private, Protected" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="False">
205 <RequiredPrefixes>
205 <RequiredPrefixes>
206 <String>m_</String>
206 <String>m_</String>
207 </RequiredPrefixes>
207 </RequiredPrefixes>
208 </NamingRule>
208 </NamingRule>
209 <NamingRule Name="Constant Fields" AffectedEntity="ConstantField" VisibilityMask="VisibilityMask" NamingStyle="AllUpper" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
209 <NamingRule Name="Constant Fields" AffectedEntity="ConstantField" VisibilityMask="VisibilityMask" NamingStyle="AllUpper" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
210 <NamingRule Name="Properties" AffectedEntity="Property" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
210 <NamingRule Name="Properties" AffectedEntity="Property" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
211 <NamingRule Name="Events" AffectedEntity="Event" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
211 <NamingRule Name="Events" AffectedEntity="Event" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
212 <NamingRule Name="Enum Members" AffectedEntity="EnumMember" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
212 <NamingRule Name="Enum Members" AffectedEntity="EnumMember" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
213 <NamingRule Name="Parameters" AffectedEntity="Parameter, LocalVariable" VisibilityMask="VisibilityMask" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
213 <NamingRule Name="Parameters" AffectedEntity="Parameter, LocalVariable" VisibilityMask="VisibilityMask" NamingStyle="CamelCase" IncludeInstanceMembers="True" IncludeStaticEntities="True" />
214 <NamingRule Name="Type Parameters" AffectedEntity="TypeParameter" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
214 <NamingRule Name="Type Parameters" AffectedEntity="TypeParameter" VisibilityMask="VisibilityMask" NamingStyle="PascalCase" IncludeInstanceMembers="True" IncludeStaticEntities="True">
215 <RequiredPrefixes>
215 <RequiredPrefixes>
216 <String>T</String>
216 <String>T</String>
217 </RequiredPrefixes>
217 </RequiredPrefixes>
218 </NamingRule>
218 </NamingRule>
219 </Rules>
219 </Rules>
220 </NameConventionPolicy>
220 </NameConventionPolicy>
221 </Policies>
221 </Policies>
222 </Properties>
222 </Properties>
223 </MonoDevelop>
223 </MonoDevelop>
224 </ProjectExtensions>
224 </ProjectExtensions>
225 </Project> No newline at end of file
225 </Project>
@@ -1,90 +1,60
1 using System;
1 using Implab.Parallels;
2 using Implab.Parallels;
2 using System;
3 using System.Threading;
3 using System.Threading;
4 using System.Diagnostics;
4
5 using System.Diagnostics.CodeAnalysis;
5 namespace Implab {
6
6 /// <summary>
7 namespace Implab {
7 /// Базовый класс для создания пулов объектов.
8 public abstract class ObjectPool<T> : IDisposable {
8 /// </summary>
9 readonly int m_size;
9 /// <remarks>
10 readonly MTQueue<T> m_queue = new MTQueue<T>();
10 /// <para>Пул объектов позволяет многократно использовать один и тотже объект,
11
11 /// что актуально для объектов, создание которых требует существенных ресурсов.
12 [SuppressMessage("Microsoft.Design", "CA1000:DoNotDeclareStaticMembersOnGenericTypes")]
12 /// Пул объектов использует слабые ссылки, чтобы не препятствовать освобождению
13 static readonly bool _isValueType = typeof(T).IsValueType;
13 /// ресурсов и создает новые объекты при необходимости.</para>
14
14 /// <para>
15 bool m_disposed;
15 /// Наследники должны реализовывать метод <see cref="CreateInstance()"/> для создания
16
16 /// новых экземпляров.
17 int m_count;
17 /// </para>
18
18 /// <para>Пул поддерживает обращения сразу из нескольких потоков.</para>
19 protected ObjectPool(int size) {
19 /// </remarks>
20 m_size = size;
20 public abstract class ObjectPool<T> where T : class {
21 }
21 readonly MTQueue<WeakReference> m_queue = new MTQueue<WeakReference>();
22
22 readonly int m_size;
23 protected ObjectPool() : this(Environment.ProcessorCount+1) {
23 int m_count = 0;
24 }
24
25
25 protected ObjectPool() : this(Environment.ProcessorCount+1) {
26 public T Allocate() {
26
27 if (m_disposed)
27 }
28 throw new ObjectDisposedException(ToString());
28
29
29 protected ObjectPool(int size) {
30 T instance;
30 Safe.ArgumentInRange(size,1,size,"size");
31 if (m_queue.TryDequeue(out instance)) {
31
32 Interlocked.Decrement(ref m_count);
32 m_size = size;
33 } else {
33 }
34 instance = CreateInstance();
34
35 Debug.Assert(!Object.Equals(instance, default(T)) || _isValueType);
35 protected abstract T CreateInstance();
36 }
36
37 return instance;
37 protected virtual void CleanupInstance(T instance) {
38 }
38 }
39
39
40 protected abstract T CreateInstance();
40 public T Allocate() {
41
41 WeakReference reference;
42 protected virtual void CleanupInstance(T instance) {
42 while (m_queue.TryDequeue(out reference)) {
43 }
43 Interlocked.Decrement(ref m_count);
44
44 object instance = reference.Target;
45 public void Release(T instance) {
45 if (instance == null)
46 if ( Object.Equals(instance,default(T)) && !_isValueType)
46 continue;
47 return;
47 return (T)instance;
48
48 }
49 Thread.MemoryBarrier();
49 return CreateInstance();
50 if (m_count < m_size && !m_disposed) {
50 }
51 Interlocked.Increment(ref m_count);
51
52
52 public void Release(T instance) {
53 CleanupInstance(instance);
53 if (m_count < m_size && instance != null) {
54
54 Interlocked.Increment(ref m_count);
55 m_queue.Enqueue(instance);
55 CleanupInstance(instance);
56
56 m_queue.Enqueue(new WeakReference(instance));
57 // пока элемент возвращался в кеш, была начата операция освобождения всего кеша
57 }
58 // и возможно уже законцена, в таком случае следует извлечь элемент обратно и
58 }
59 // освободить его. Если операция освобождения кеша еще не заврешилась, то будет
59 }
60 // изъят и освобожден произвольный элемен, что не повлияет на ход всего процесса.
60 }
61 if (m_disposed && m_queue.TryDequeue(out instance) && instance is IDisposable)
62 ((IDisposable)instance).Dispose() ;
63
64 } else {
65 if (instance is IDisposable)
66 ((IDisposable)instance).Dispose();
67 }
68 }
69
70 protected virtual void Dispose(bool disposing) {
71 if (disposing) {
72 m_disposed = true;
73 T instance;
74 while (m_queue.TryDequeue(out instance))
75 if (instance is IDisposable)
76 ((IDisposable)instance).Dispose();
77 }
78 }
79
80 #region IDisposable implementation
81
82 public void Dispose() {
83 Dispose(true);
84 GC.SuppressFinalize(this);
85 }
86
87 #endregion
88 }
89 }
90
@@ -1,248 +1,248
1 using System;
1 using System;
2 using System.Collections.Generic;
2 using System.Collections.Generic;
3
3
4 namespace Implab {
4 namespace Implab {
5 /// <summary>
5 /// <summary>
6 /// Коллекция сервисов, позволяет регистрировать и получать сервисы.
6 /// Коллекция сервисов, позволяет регистрировать и получать сервисы.
7 /// </summary>
7 /// </summary>
8 public class ServiceLocator: Component, IServiceLocator, IServiceProvider {
8 public class ServiceLocator: Disposable, IServiceLocator, IServiceProvider {
9 // запись о сервисе
9 // запись о сервисе
10 struct ServiceEntry : IDisposable {
10 struct ServiceEntry : IDisposable {
11 public object service; // сервис
11 public object service; // сервис
12 public bool shared; // признак того, что сервис НЕ нужно освобождать
12 public bool shared; // признак того, что сервис НЕ нужно освобождать
13 public Func<object> activator; // активатор сервиса при первом обращении
13 public Func<object> activator; // активатор сервиса при первом обращении
14 public Action<object> cleanup; // функция для очистки сервиса
14 public Action<object> cleanup; // функция для очистки сервиса
15 public List<Type> associated; // ссылки на текущую запись
15 public List<Type> associated; // ссылки на текущую запись
16 public Type origin; // ссылка на оригинальную запись о сервисе
16 public Type origin; // ссылка на оригинальную запись о сервисе
17
17
18 #region IDisposable implementation
18 #region IDisposable implementation
19
19
20 public void Dispose() {
20 public void Dispose() {
21 if (shared)
21 if (shared)
22 return;
22 return;
23 if (cleanup != null) {
23 if (cleanup != null) {
24 if (service != null)
24 if (service != null)
25 cleanup(service);
25 cleanup(service);
26 } else
26 } else
27 Safe.Dispose(service);
27 Safe.Dispose(service);
28 }
28 }
29
29
30 #endregion
30 #endregion
31 }
31 }
32
32
33 // словарь существующих сервисов
33 // словарь существующих сервисов
34 readonly Dictionary<Type, ServiceEntry> m_services = new Dictionary<Type,ServiceEntry>();
34 readonly Dictionary<Type, ServiceEntry> m_services = new Dictionary<Type,ServiceEntry>();
35
35
36 /// <summary>
36 /// <summary>
37 /// Получает объект предоставляющий сервис <typeparamref name="T"/>.
37 /// Получает объект предоставляющий сервис <typeparamref name="T"/>.
38 /// </summary>
38 /// </summary>
39 /// <typeparam name="T">Тип запрашиваемого сервиса</typeparam>
39 /// <typeparam name="T">Тип запрашиваемого сервиса</typeparam>
40 /// <returns>Объект, реализующий сервис</returns>
40 /// <returns>Объект, реализующий сервис</returns>
41 /// <exception cref="KeyNotFoundException">Сервис не зарегистрирован</exception>
41 /// <exception cref="KeyNotFoundException">Сервис не зарегистрирован</exception>
42 public T GetService<T>() {
42 public T GetService<T>() {
43 object result;
43 object result;
44 if (TryGetService(typeof(T), out result))
44 if (TryGetService(typeof(T), out result))
45 return (T)result;
45 return (T)result;
46 throw new ApplicationException (String.Format ("{0} doesn't provide {1} service", this, typeof(T)));
46 throw new ApplicationException (String.Format ("{0} doesn't provide {1} service", this, typeof(T)));
47 }
47 }
48
48
49
49
50 /// <summary>
50 /// <summary>
51 /// Пытается получить указанный сервис, в случае, если компонента не предоставляет требуемый сервис
51 /// Пытается получить указанный сервис, в случае, если компонента не предоставляет требуемый сервис
52 /// не возникает исключений.
52 /// не возникает исключений.
53 /// </summary>
53 /// </summary>
54 /// <typeparam name="T">Тип требуемого сервиса.</typeparam>
54 /// <typeparam name="T">Тип требуемого сервиса.</typeparam>
55 /// <param name="service">Объект реализующий сервис, или <c>default(T)</c> если такового нет.</param>
55 /// <param name="service">Объект реализующий сервис, или <c>default(T)</c> если такового нет.</param>
56 /// <returns><c>true</c> - сервис найден, <c>false</c> - сервис не зарегистрирован.</returns>
56 /// <returns><c>true</c> - сервис найден, <c>false</c> - сервис не зарегистрирован.</returns>
57 public bool TryGetService<T>(out T service) {
57 public bool TryGetService<T>(out T service) {
58 object result;
58 object result;
59 if (TryGetService(typeof(T), out result)) {
59 if (TryGetService(typeof(T), out result)) {
60 service = (T)result;
60 service = (T)result;
61 return true;
61 return true;
62 }
62 }
63 service = default(T);
63 service = default(T);
64 return false;
64 return false;
65 }
65 }
66
66
67 /// <summary>
67 /// <summary>
68 /// Получает объект предоставляющий сервис <paramref name="serviceType"/>
68 /// Получает объект предоставляющий сервис <paramref name="serviceType"/>
69 /// </summary>
69 /// </summary>
70 /// <param name="serviceType">Тип запрашиваемого сервиса</param>
70 /// <param name="serviceType">Тип запрашиваемого сервиса</param>
71 /// <returns>Объект, реализующий сервис</returns>
71 /// <returns>Объект, реализующий сервис</returns>
72 /// <exception cref="KeyNotFoundException">Сервис не зарегистрирован</exception>
72 /// <exception cref="KeyNotFoundException">Сервис не зарегистрирован</exception>
73 public object GetService(Type serviceType) {
73 public object GetService(Type serviceType) {
74 object result;
74 object result;
75 if (TryGetService(serviceType, out result))
75 if (TryGetService(serviceType, out result))
76 return result;
76 return result;
77 throw new ApplicationException (String.Format ("{0} doesn't provide {1} service", this, serviceType));
77 throw new ApplicationException (String.Format ("{0} doesn't provide {1} service", this, serviceType));
78 }
78 }
79
79
80 /// <summary>
80 /// <summary>
81 /// Пытается получить требуемый сервис или совместимый с ним.
81 /// Пытается получить требуемый сервис или совместимый с ним.
82 /// </summary>
82 /// </summary>
83 /// <returns><c>true</c>, если сервис был найден, <c>false</c> в противном случае..</returns>
83 /// <returns><c>true</c>, если сервис был найден, <c>false</c> в противном случае..</returns>
84 /// <param name="serviceType">Тип запрашиваемого сервиса.</param>
84 /// <param name="serviceType">Тип запрашиваемого сервиса.</param>
85 /// <param name="service">Искомый сервис.</param>
85 /// <param name="service">Искомый сервис.</param>
86 public virtual bool TryGetService(Type serviceType, out object service) {
86 public virtual bool TryGetService(Type serviceType, out object service) {
87 Safe.ArgumentNotNull(serviceType, "serviceType");
87 Safe.ArgumentNotNull(serviceType, "serviceType");
88 AssertNotDisposed();
88 AssertNotDisposed();
89
89
90 ServiceEntry se;
90 ServiceEntry se;
91 if (!m_services.TryGetValue(serviceType, out se)) {
91 if (!m_services.TryGetValue(serviceType, out se)) {
92 // ищем ближайщий объект, реализующий нужный сервис
92 // ищем ближайщий объект, реализующий нужный сервис
93 Type pt = null;
93 Type pt = null;
94 foreach (var t in m_services.Keys)
94 foreach (var t in m_services.Keys)
95 if (serviceType.IsAssignableFrom(t) && (pt == null || t.IsAssignableFrom(pt)))
95 if (serviceType.IsAssignableFrom(t) && (pt == null || t.IsAssignableFrom(pt)))
96 pt = t;
96 pt = t;
97
97
98 if (pt == null) {
98 if (pt == null) {
99 // нет нужного сервиса
99 // нет нужного сервиса
100 service = null;
100 service = null;
101 return false;
101 return false;
102 }
102 }
103
103
104 var pe = m_services[pt];
104 var pe = m_services[pt];
105
105
106 // найденная запись может ссылаться на оригинальную запись с сервисом
106 // найденная запись может ссылаться на оригинальную запись с сервисом
107 if(pe.origin != null) {
107 if(pe.origin != null) {
108 pt = pe.origin;
108 pt = pe.origin;
109 pe = m_services[pt];
109 pe = m_services[pt];
110 }
110 }
111
111
112 // добавляем список с обратными ссылками
112 // добавляем список с обратными ссылками
113 if (pe.associated == null)
113 if (pe.associated == null)
114 pe.associated = new List<Type>();
114 pe.associated = new List<Type>();
115
115
116 pe.associated.Add(serviceType);
116 pe.associated.Add(serviceType);
117
117
118 // обновляем родительскую запись
118 // обновляем родительскую запись
119 m_services[pt] = pe;
119 m_services[pt] = pe;
120
120
121 // создаем запись со ссылкой
121 // создаем запись со ссылкой
122 se = new ServiceEntry {
122 se = new ServiceEntry {
123 service = pe.service,
123 service = pe.service,
124 origin = pt,
124 origin = pt,
125 shared = true // предотвращаем множественные попытки освобождения
125 shared = true // предотвращаем множественные попытки освобождения
126 };
126 };
127
127
128 m_services[serviceType] = se;
128 m_services[serviceType] = se;
129 }
129 }
130
130
131 // запись содержит в себе информацию о сервисе
131 // запись содержит в себе информацию о сервисе
132 if (se.service != null) {
132 if (se.service != null) {
133 service = se.service;
133 service = se.service;
134 return true;
134 return true;
135 }
135 }
136
136
137 // текущая запись является ссылкой
137 // текущая запись является ссылкой
138 if (se.origin != null) {
138 if (se.origin != null) {
139 se.service = GetService(se.origin);
139 se.service = GetService(se.origin);
140 m_services[serviceType] = se;
140 m_services[serviceType] = se;
141 service = se.service;
141 service = se.service;
142 return true;
142 return true;
143 }
143 }
144
144
145 // текущая запись не является ссылкой и не имеет информации о сервисе
145 // текущая запись не является ссылкой и не имеет информации о сервисе
146 // она должна сожержать информацию об активации
146 // она должна сожержать информацию об активации
147 if (se.activator != null) {
147 if (se.activator != null) {
148 se.service = se.activator();
148 se.service = se.activator();
149
149
150 m_services[serviceType] = se;
150 m_services[serviceType] = se;
151
151
152 service = se.service;
152 service = se.service;
153 return true;
153 return true;
154 }
154 }
155
155
156 service = null;
156 service = null;
157 return false;
157 return false;
158 }
158 }
159
159
160 /// <summary>
160 /// <summary>
161 /// Регистрирует фабрику для активации сервиса по первому требованию.
161 /// Регистрирует фабрику для активации сервиса по первому требованию.
162 /// </summary>
162 /// </summary>
163 /// <typeparam name="T">Тип регистрируемого сервиса.</typeparam>
163 /// <typeparam name="T">Тип регистрируемого сервиса.</typeparam>
164 /// <param name="activator">Фабрика для создания/получения объекта, предоставляющего сервис.</param>
164 /// <param name="activator">Фабрика для создания/получения объекта, предоставляющего сервис.</param>
165 /// <param name = "cleanup">Метод для освобождения экземпляра сервиса, будет вызыван при освобождении сервис-локатора.</param>
165 /// <param name = "cleanup">Метод для освобождения экземпляра сервиса, будет вызыван при освобождении сервис-локатора.</param>
166 /// <remarks>При освобождении сервис-локатора, сервисы полученные в результате активации также будут освобождены.</remarks>
166 /// <remarks>При освобождении сервис-локатора, сервисы полученные в результате активации также будут освобождены.</remarks>
167 public void Register<T>(Func<T> activator, Action<T> cleanup) {
167 public void Register<T>(Func<T> activator, Action<T> cleanup) {
168 Safe.ArgumentNotNull(activator, "activator");
168 Safe.ArgumentNotNull(activator, "activator");
169
169
170 AssertNotDisposed();
170 AssertNotDisposed();
171
171
172 Unregister(typeof(T));
172 Unregister(typeof(T));
173
173
174 var serviceEntry = new ServiceEntry();
174 var serviceEntry = new ServiceEntry();
175 serviceEntry.activator = () => activator();
175 serviceEntry.activator = () => activator();
176 if (cleanup != null)
176 if (cleanup != null)
177 serviceEntry.cleanup = instance => cleanup((T)instance);
177 serviceEntry.cleanup = instance => cleanup((T)instance);
178 m_services[typeof(T)] = serviceEntry;
178 m_services[typeof(T)] = serviceEntry;
179 }
179 }
180
180
181 public void Register<T>(Func<T> activator) {
181 public void Register<T>(Func<T> activator) {
182 Register(activator, null);
182 Register(activator, null);
183 }
183 }
184
184
185 /// <summary>
185 /// <summary>
186 /// Регистрирует объект, предоставляющий сервис.
186 /// Регистрирует объект, предоставляющий сервис.
187 /// </summary>
187 /// </summary>
188 /// <typeparam name="T">Тип регистрируемого сервиса.</typeparam>
188 /// <typeparam name="T">Тип регистрируемого сервиса.</typeparam>
189 /// <param name="service">Объект, предоставляющий сервис.</param>
189 /// <param name="service">Объект, предоставляющий сервис.</param>
190 /// <exception cref="InvalidOperationException">Указанный сервис уже зарегистрирован.</exception>
190 /// <exception cref="InvalidOperationException">Указанный сервис уже зарегистрирован.</exception>
191 /// <remarks>Сервис-локатором не управляет временем жизни объекта для зарегистрированного сервиса.</remarks>
191 /// <remarks>Сервис-локатором не управляет временем жизни объекта для зарегистрированного сервиса.</remarks>
192 public void Register<T>(T service) {
192 public void Register<T>(T service) {
193 Register(service, true);
193 Register(service, true);
194 }
194 }
195
195
196 /// <summary>
196 /// <summary>
197 /// Регистрирует объект, предоставляющий сервис. Повторная регистрация отменяет уже существующую.
197 /// Регистрирует объект, предоставляющий сервис. Повторная регистрация отменяет уже существующую.
198 /// </summary>
198 /// </summary>
199 /// <typeparam name="T">Тип регистрируемого сервиса.</typeparam>
199 /// <typeparam name="T">Тип регистрируемого сервиса.</typeparam>
200 /// <param name="service">Объект, предоставляющий сервис.</param>
200 /// <param name="service">Объект, предоставляющий сервис.</param>
201 /// <param name="shared">Признак того, что объект является разделяемым и сервис-локатор не должен его освобождать.</param>
201 /// <param name="shared">Признак того, что объект является разделяемым и сервис-локатор не должен его освобождать.</param>
202 public void Register<T>(T service, bool shared) {
202 public void Register<T>(T service, bool shared) {
203 Safe.ArgumentNotNull(service, "service");
203 Safe.ArgumentNotNull(service, "service");
204
204
205 AssertNotDisposed();
205 AssertNotDisposed();
206
206
207 Unregister(typeof(T));
207 Unregister(typeof(T));
208
208
209 m_services[typeof(T)] = new ServiceEntry { service = service, shared = shared };
209 m_services[typeof(T)] = new ServiceEntry { service = service, shared = shared };
210 }
210 }
211
211
212 public void Unregister(Type serviceType) {
212 public void Unregister(Type serviceType) {
213 Safe.ArgumentNotNull(serviceType, "serviceType");
213 Safe.ArgumentNotNull(serviceType, "serviceType");
214
214
215 AssertNotDisposed();
215 AssertNotDisposed();
216
216
217 ServiceEntry se;
217 ServiceEntry se;
218 if (m_services.TryGetValue(serviceType, out se)) {
218 if (m_services.TryGetValue(serviceType, out se)) {
219 if (se.origin != null) {
219 if (se.origin != null) {
220 var pe = m_services[se.origin];
220 var pe = m_services[se.origin];
221 pe.associated.Remove(serviceType);
221 pe.associated.Remove(serviceType);
222 }
222 }
223 // освобождаем ресурсы
223 // освобождаем ресурсы
224 se.Dispose();
224 se.Dispose();
225 m_services.Remove(serviceType);
225 m_services.Remove(serviceType);
226
226
227 // убираем связанные записи
227 // убираем связанные записи
228 if (se.associated != null)
228 if (se.associated != null)
229 foreach (var item in se.associated)
229 foreach (var item in se.associated)
230 m_services.Remove(item);
230 m_services.Remove(item);
231 }
231 }
232 }
232 }
233
233
234 /// <summary>
234 /// <summary>
235 /// Освобождает зарегистрированные сервисы (которые требуется освобоить).
235 /// Освобождает зарегистрированные сервисы (которые требуется освобоить).
236 /// </summary>
236 /// </summary>
237 /// <param name="disposing">Призанак того, что нужно освободить ресурсы.</param>
237 /// <param name="disposing">Призанак того, что нужно освободить ресурсы.</param>
238 protected override void Dispose(bool disposing) {
238 protected override void Dispose(bool disposing) {
239 if (disposing) {
239 if (disposing) {
240
240
241 foreach (var entry in m_services.Values)
241 foreach (var entry in m_services.Values)
242 entry.Dispose();
242 entry.Dispose();
243
243
244 }
244 }
245 base.Dispose(disposing);
245 base.Dispose(disposing);
246 }
246 }
247 }
247 }
248 } No newline at end of file
248 }
1 NO CONTENT: file was removed
NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now