-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathREADME.md.template
147 lines (109 loc) · 8.32 KB
/
README.md.template
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
## NOTE, following is a very high level description of **IoC.Configuration**. For more details please refer to a more complete documentation at [http://iocconfiguration.readthedocs.io](http://iocconfiguration.readthedocs.io), and also look at configuration files in [https://github.com/artakhak/IoC.Configuration/tree/master/IoC.Configuration.Tests](https://github.com/artakhak/IoC.Configuration/tree/master/IoC.Configuration.Tests) and the tests that use these files.
***
The main functions of IoC.Configuration library are:
1) Container agnostic configuration of dependency injection using XML configuration file. The file has section where container can be specified, that will be handling dependency injection resolutions.
Currently two popular containers are supported, **Ninject** and **Autofac**, via extension libraries **IoC.Configuration.Ninject** and **IoC.Configuration.Autofac**, that are available in Nuget.org.
The dependency injection container (e.g., **Autofac**, **Ninject**) can be easily switched in configuration file.
In addition, the configuration file has sections for settings, plugins, startup actions, dynamically generated implementations of interfaces (see elements **iocConfiguration/dependencyInjection/autoGeneratedServices/autoService** and **iocConfiguration/dependencyInjection/autoGeneratedServices/autoServiceCustom** in example configuration files in GitHub test project [IoC.Configuration.Tests](https://github.com/artakhak/IoC.Configuration/tree/master/IoC.Configuration.Tests)).
2) Container agnostic configuration of dependency injection in code.
***
The bindings are specified using **IoC.Configuration** chained methods, however the actual resolutions are done using one of the popular dependency injection containers, **Ninject** and **Autofac**, via extension libraries **IoC.Configuration.Ninject** and **IoC.Configuration.Autofac**.
***
## Configuration
Dependency injection can be configured either using file based or code based configuration builder.
Bindings can be specified in three different ways:
-In configuration file (for file based configuration only).
-Using native modules (for example using Autofac and Ninject modules).
-By extending the class IoC.Configuration.DiContainer.ModuleAbstr and overriding the method AddServiceRegistrations() or by implementing IoC.Configuration.IDiModule.
In file based configuration, the modules (Autofac, Ninject, or implementations of IoC.Configuration.IDiModule) can be specified in configuration file in element iocConfiguration/dependencyInjection/modules/module
In code based configuration, the modules can be passed as parameters in chained configuration methods (see the section Code Based Configuration).
**Below is an example of specifying bindings in AddServiceRegistrations() method in a subclass of IoC.Configuration.DiContainer.ModuleAbstr (note the example is taken from test project so the class names are not user friendly).**
```csharp
<IncludedFilePlaceHolder>IoC.Configuration.Tests\SuccessfulDiModuleLoadTests\TestDiModule.cs</IncludedFilePlaceHolder>
```
## File Based Configuration
Example of configuration file is shown below.
Here is an example of configuring and starting the container:
```csharp
TestsSharedLibrary.TestsHelper.SetupLogger();
var configurationFileContentsProvider = new FileBasedConfigurationFileContentsProvider(
Path.Combine(Helpers.TestsEntryAssemblyFolder, "IoCConfiguration_Overview.xml"));
using (var containerInfo = new DiContainerBuilder.DiContainerBuilder()
.StartFileBasedDi(
new FileBasedConfigurationParameters(configurationFileContentsProvider,
Helpers.TestsEntryAssemblyFolder,
new LoadedAssembliesForTests())
{
AdditionalReferencedAssemblies = new []
{
// List additional assemblies that should be added to dynamically generated assembly as references
Path.Combine(Helpers.GetTestFilesFolderPath(), @"DynamicallyLoadedDlls\TestProjects.DynamicallyLoadedAssembly1.dll"),
Path.Combine(Helpers.GetTestFilesFolderPath(), @"DynamicallyLoadedDlls\TestProjects.DynamicallyLoadedAssembly2.dll")
},
AttributeValueTransformers = new[] {new FileFolderPathAttributeValueTransformer()},
ConfigurationFileXmlDocumentLoaded = (sender, e) =>
{
// Replace some elements in e.XmlDocument if needed,
// before the configuration is loaded.
Helpers.EnsureConfigurationDirectoryExistsOrThrow(e.XmlDocument.SelectElement("/iocConfiguration/appDataDir").GetAttribute("path"));
}
}, out _)
.WithoutPresetDiContainer()
.AddAdditionalDiModules(new TestDiModule())
.RegisterModules()
.Start())
{
var container = containerInfo.DiContainer;
Assert.IsNotNull(containerInfo.DiContainer.Resolve<IInterface6>());
var settings = container.Resolve<ISettings>();
Assert.AreEqual(155.7, settings.GetSettingValueOrThrow<double>("MaxCharge"));
var pluginRepository = container.Resolve<IPluginDataRepository>();
var pluginData = pluginRepository.GetPluginData("Plugin1");
Assert.AreEqual(38, pluginData.Settings.GetSettingValueOrThrow<long>("Int64Setting1"));
}
```
**The configuration file IoCConfiguration_Overview.xml available in [https://github.com/artakhak/IoC.Configuration/tree/master/IoC.Configuration.Tests](https://github.com/artakhak/IoC.Configuration/tree/master/IoC.Configuration.Tests)**
```XML
<IncludedFilePlaceHolder>IoC.Configuration.Tests\IoCConfiguration_Overview.xml</IncludedFilePlaceHolder>
```
## Code Based Configuration
Code based configuration is pretty similar to file based configuration, except there is no configuration file.
All dependencies are bound in IoC.Configuration modules (i.e., instances IoC.Configuration.DiContainer.IDiModule) native modules (e.g., instances of Autofac.AutofacModule or Ninject.Modules.NinjectModule)
Here is an example of code based configuration.
```csharp
TestsSharedLibrary.TestsHelper.SetupLogger();
// Probing paths are used to re-solve the dependencies.
var assemblyProbingPaths = new string[]
{
DiManagerHelpers.ThirdPartyLibsFolder,
DiManagerHelpers.DynamicallyLoadedDllsFolder,
DiManagerHelpers.GetDiImplementationInfo(DiImplementationType.Autofac).DiManagerFolder
};
var diImplementationInfo = DiManagerHelpers.GetDiImplementationInfo(DiImplementationType.Autofac);
using (var containerInfo =
new DiContainerBuilder.DiContainerBuilder()
.StartCodeBasedDi("IoC.Configuration.Autofac.AutofacDiManager",
diImplementationInfo.DiManagerAssemblyPath,
new ParameterInfo[0],
Helpers.TestsEntryAssemblyFolder,
assemblyProbingPaths)
.WithoutPresetDiContainer()
// Note, AddNativeModule() to add native modules (e.g., instances of Autofac.AutofacModule or
// Ninject.Modules.NinjectModule) // and AddDiModules to add IoC.Configuration modules (i.e.,
// instances IoC.Configuration.DiContainer.IDiModule), can be called multiple times, without
// any restriction on the order in which these methods are called.
.AddNativeModule("Modules.Autofac.AutofacModule1",
Path.Combine(DiManagerHelpers.DynamicallyLoadedDllsFolder, "TestProjects.Modules.dll"),
new[] { new ParameterInfo(typeof(int), 18) })
.AddDiModules(new TestDiModule())
.RegisterModules()
.Start())
{
var container = containerInfo.DiContainer;
Assert.IsNotNull(containerInfo.DiContainer.Resolve<IInterface6>());
}
```
## Native and IoC.Configuration modules in configuration file.
Both native modules (e.g., subclasses of Autofac.AutofacModule or Ninject.Modules.NinjectModule) and IoC.Configuration modules can be specified in configuration files.
Here is an example from configuration file above which has both native and container agnostic IoC.Configuration modules.
