Hi Community,
Today’s post is about an IoC library I wrote back in 2013. I called it “LightIoc” because it’s self-contained in a single assembly file. Over the years I have used a few IoC libraries some of them are easy to use, others a bit bulkier or with more dependant assemblies but for this one I added a few custom features as mentioned below:
- Pre-jitting of assemblies to improve start-up performance. This is configuration driven
- Discovery of assemblies at start-up
- Configuration and registration of types via code or config files
- Lifespan of objects, in other words, objects that are required to do something then are self-disposed
///////////////////////
// Sample config file//
///////////////////////
<configuration>
<configSections>
<section name="LightIoC" allowLocation="false" allowDefinition="Everywhere"
type="LightIoC.Configuration.ConfigReader, LightIoC, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
</configSections>
<LightIoC>
<Pre-Jitting enabled="true"/>
<registrations>
<register name="IDispatchMessageInspector" />
<register name="ITestLib" type="WebAPI.Core.Interfaces.ITestLib" assemblyFQN="WebAPI.Core.Interfaces, Version=1.0.0.0, Culture=neutral, PublicKeyToken=23e52edaf0ea7bd4" />
<register name="IWebApiLogger" type="WebAPI.Core.Interfaces.IWebApiLogger" assemblyFQN="WebAPI.Core.Interfaces, Version=1.0.0.0, Culture=neutral, PublicKeyToken=23e52edaf0ea7bd4" />
<register name="IWebApiPerfCounter" type="WebAPI.Core.Interfaces.IWebApiLogger" assemblyFQN="WebAPI.Core.Interfaces, Version=1.0.0.0, Culture=neutral, PublicKeyToken=23e52edaf0ea7bd4" />
</registrations>
<mappings>
<map abstraction="IWebApiLogger" to="DefaultLogger" instanceRequired="true" />
<map abstraction="IWebApiPerfCounter" to="WebApiPerfCounter" instanceRequired="true" />
<map abstraction="IDispatchMessageInspector" to="MessageInspector" instanceRequired="true" />
<map abstraction="ITestLib" to="ThisIsADestroyableClass" instanceRequired="true" lifeSpan="300" />
</mappings>
</LightIoC>
</configuration?
Alternatively I could have also registered my type container in code, as shown. Type registration can take a Type as such or also the name of the type as string, hence validation occurs at initialization of the container.
public void InitializeTypeContainer<T>() where T: System.ComponentModel.Component {
if (!TypeContainerInitialized) {
TypeContainer.Current.RegisterType<IUnifiedShell>("UnifiedShell");
TypeContainer.Current.RegisterType<IShellConfig>("ShellConfig");
TypeContainer.Current.RegisterType<ILogger>("Logger", true);
TypeContainer.Current.RegisterType<IAgentService>("AgentService");
TypeContainer.Current.RegisterType<IAutomationResult>("AutomationResult");
TypeContainer.Current.RegisterType<IAutomationRequest>("AutomationRequest");
TypeContainer.Current.RegisterType<IPerfCounters>("PerfCounters", true);
TypeContainer.Current.RegisterType<IServiceOperation>("ServiceOperation");
TypeContainer.Current.RegisterType<IServiceInformation>("CustomServiceBase", true);
TypeContainer.Current.RegisterType<IBaseService<T>>(typeof(T).Name, true);
TypeContainer.Current.RegisterType<IAutomationEngine>(TypeContainer.Current.Resolve<IBaseService<T>>());
}
}
I hope you find this useful. Source code is available here
Regards,
Angel