Partager via


TypeC - A Simple .NET Dependency Injection / IoC Container

TypeC is a simple .NET type container for resolving interfaces/abstract base classes to their concrete implementations. TypeC implements factory method for instantiating types. Only one container can exist in a given .NET AppDomain as it is a singleton implementation. Multiple concrete child types can be mapped to the same base class through namespace support.

The project repo is located at https://github.com/hanuk/typec; the nuget package can be installed using the command: "Install-Package TypeC" from the NuGet Package Manager Console inside Visual Studio.

The following snippets show the sample usage:

 //during the startup 
 TypeContainer typeC = TypeContainer.Instance; 
 typeC.Register<IList<string>, List<string>>(); 

 //bind the interface to an implementation
 var list = typeC.GetInstance<IList<string>>(); 
  list.Add("test"); 
  
 With namespace support:
  //during the startup 
 string namespace = "MyNamespace"; 
 TypeContainer typeC = TypeContainer.Instance; 
 typeC.Register<IList<string>, List<string>>(namespace); //deep inside the layers of the code 
 var list = typeC.GetInstance<IList<string>>(namespace); list.Add("test"); 
 

Loading type mapping from a configuration file:

 //during the startup 
 string fileName = "TypeConfig.xml"; 
 TypeContainer tc = TypeContainer.Instance; 
 //the Load(fileName) will fail if types can't be resolved tc.Load(fileName); 
 
  //bind the interface to an implementation
 IGenericWriter<MyClass> writer1 = tc.GetInstance<IGenericWriter<MyClass>>("gwriter3"); 
 writer1.Write(new MyClass()); 
 IGenericWriter<MyClass> writer2 = tc.GetInstance<IGenericWriter<MyClass>>("gwriter4"); 

Sample XML configuration file is located in TypeC.Tests project. The file follows the standard reflection notation: https://msdn.microsoft.com/en-us/library/w3f99sx1(v=vs.110).aspx

TypeContainer.GetRegistryAsXml() will dump the registry for easy configuration file creation and debugging. The returned XML string can be pasted into the configuration file so that complex generic types can be defined easily for dynamic binding.

The sample xml configuration snippet returned by TypeContainer.GetRegistryAsXml()is shown below:

 //code snippet 
 TypeContainer tc = TypeContainer.Instance;
tc.Register<IWriter, Lib1Writer1>("writer1");
tc.Register<IWriter, Lib2Writer1>("writer2");
tc.Register<IGenericWriter<string>, Lib1GenericWriter1>("gwriter1");
tc.Register<IGenericWriter<string>, Lib2GenericWriter1>("gwriter2");
tc.Register<IGenericWriter<MyClass>, Lib1GenericWriter2>("gwriter3");
tc.Register<IGenericWriter<MyClass>, Lib2GenericWriter2>("gwriter4");
 
 string xml = tc.GetRegistryAsXml();
 //corresponding XML
 <typecmap>
 <mapping namespace="writer1" from="TypeC.Tests.Shared.IWriter,TypeC.Tests.Shared" to="TypeC.Tests.Lib1.Lib1Writer1, TypeC.Tests.Lib1"/>
 <mapping namespace="writer2" from="TypeC.Tests.Shared.IWriter,TypeC.Tests.Shared" to="TypeC.Tests.Lib1.Lib1Writer2, TypeC.Tests.Lib1"/> 
 <mapping namespace="gwriter1" from="TypeC.Tests.Shared.IGenericWriter`1[[System.String, mscorlib]], TypeC.Tests.Shared" to ="TypeC.Tests.Lib1.Lib1GenericWriter1, TypeC.Tests.Lib1"/> 
 <mapping namespace="gwriter2" from="TypeC.Tests.Shared.IGenericWriter`1[[System.String, mscorlib]], TypeC.Tests.Shared" to ="TypeC.Tests.Lib2.Lib2GenericWriter1, TypeC.Tests.Lib2"/> 
 <mapping namespace="gwriter3" from="TypeC.Tests.Shared.IGenericWriter`1[[TypeC.Tests.Model.MyClass, TypeC.Tests.Model]], TypeC.Tests.Shared" to ="TypeC.Tests.Lib1.Lib1GenericWriter2, TypeC.Tests.Lib1"/> 
 <mapping namespace="gwriter4" from="TypeC.Tests.Shared.IGenericWriter`1[[TypeC.Tests.Model.MyClass, TypeC.Tests.Model]], TypeC.Tests.Shared" to ="TypeC.Tests.Lib2.Lib2GenericWriter2, TypeC.Tests.Lib2"/> 
</typecmap> 

If you have complex nested generic types, hand coding XML can be error prone; build your registry using code and dump xml into the configuration file.

Hope this helps.

Comments

  • Anonymous
    March 29, 2015
    The comment has been removed

  • Anonymous
    March 29, 2015
    Castle Windsor, StructureMap, Autofac, Sprint.NET, Ninject, Simple Injector, Unity... Did the world really need another IoC container? Particularly one that, as pablo points out, encourages the Service Locator anti-pattern?

  • Anonymous
    March 29, 2015
    What does this do that TinyIOC doesn't?

  • Anonymous
    March 29, 2015
    What about non-parameterless constructors? What if an uninitialised type makes no sense? SL anti-pattern and DI frameworks in general encourage multi-stage construction, i.e. cons followed by init or set methods. This is also an anti pattern

  • Anonymous
    April 01, 2015
    I'm not sure why others are concluding that this IOC promotes the service locator pattern. I'm sure it could be integrated with the MVC framework like all other IOCs to give constructor injection (think NinjectWebCommon.cs). As to why another? I suppose the dude just wanted to write one. He's shared it with the world. I might write one 1 day as well. Just because it has been done before is NEVER a reason to not bother. I'm sure he's a better coder for the experience.