diff --git a/LightweightIocContainer/Registrations/DefaultRegistration.cs b/LightweightIocContainer/Registrations/DefaultRegistration.cs
new file mode 100644
index 0000000..8b34300
--- /dev/null
+++ b/LightweightIocContainer/Registrations/DefaultRegistration.cs
@@ -0,0 +1,65 @@
+// Author: simon.gockner
+// Created: 2019-05-20
+// Copyright(c) 2019 SimonG. All Rights Reserved.
+
+using System;
+using LightweightIocContainer.Interfaces;
+using LightweightIocContainer.Interfaces.Registrations;
+
+namespace LightweightIocContainer.Registrations
+{
+ ///
+ /// The default registration that is used to register a Type for the Interface it implements
+ ///
+ /// The registered Interface
+ public class DefaultRegistration : IDefaultRegistration
+ {
+ public DefaultRegistration(Type interfaceType, Type implementationType, Lifestyle lifestyle)
+ {
+ InterfaceType = interfaceType;
+ ImplementationType = implementationType;
+ Lifestyle = lifestyle;
+
+ Name = $"{InterfaceType.Name}, {ImplementationType.Name}, Lifestyle: {Lifestyle.ToString()}";
+ }
+
+ ///
+ /// The name of the
+ ///
+ public string Name { get; }
+
+ ///
+ /// The Type of the Interface that is registered with this
+ ///
+ public Type InterfaceType { get; }
+
+ ///
+ /// The Type that implements the that is registered with this
+ ///
+ public Type ImplementationType { get; }
+
+ ///
+ /// The Lifestyle of Instances that are created with this
+ ///
+ public Lifestyle Lifestyle { get; }
+
+
+ ///
+ /// This action is invoked when an instance of this type is created.
+ /// Can be set in the by calling
+ ///
+ public Action OnCreateAction { get; private set; }
+
+
+ ///
+ /// Pass an action that will be invoked when an instance of this type is created
+ ///
+ /// The action
+ /// The current instance of this
+ public IDefaultRegistration OnCreate(Action action)
+ {
+ OnCreateAction = action;
+ return this;
+ }
+ }
+}
\ No newline at end of file
diff --git a/LightweightIocContainer/Registrations/RegistrationFactory.cs b/LightweightIocContainer/Registrations/RegistrationFactory.cs
new file mode 100644
index 0000000..fd0b0b3
--- /dev/null
+++ b/LightweightIocContainer/Registrations/RegistrationFactory.cs
@@ -0,0 +1,38 @@
+// Author: simon.gockner
+// Created: 2019-05-20
+// Copyright(c) 2019 SimonG. All Rights Reserved.
+
+using LightweightIocContainer.Interfaces;
+using LightweightIocContainer.Interfaces.Registrations;
+
+namespace LightweightIocContainer.Registrations
+{
+ ///
+ /// A factory to register interfaces and factories in an and create the needed s
+ ///
+ public static class RegistrationFactory
+ {
+ ///
+ /// Register an Interface with a Type that implements it and create a
+ ///
+ /// The Interface to register
+ /// The Type that implements the
+ /// The for this
+ /// A new created with the given parameters
+ public static IDefaultRegistration Register(Lifestyle lifestyle = Lifestyle.Transient) where TImplementation : TInterface
+ {
+ return new DefaultRegistration(typeof(TInterface), typeof(TImplementation), lifestyle);
+ }
+
+ ///
+ /// Register an Interface as an abstract typed factory and create a
+ ///
+ /// The abstract typed factory to register
+ /// The current
+ /// A new created with the given parameters
+ public static ITypedFactoryRegistration RegisterFactory(IInjectorContainer container) //TODO: Find a nicer way to inject the container into `TypedFactoryRegistration`
+ {
+ return new TypedFactoryRegistration(typeof(TFactory), container);
+ }
+ }
+}
\ No newline at end of file
diff --git a/LightweightIocContainer/Registrations/TypedFactoryRegistration.cs b/LightweightIocContainer/Registrations/TypedFactoryRegistration.cs
new file mode 100644
index 0000000..8a8097a
--- /dev/null
+++ b/LightweightIocContainer/Registrations/TypedFactoryRegistration.cs
@@ -0,0 +1,128 @@
+// Author: simon.gockner
+// Created: 2019-05-20
+// Copyright(c) 2019 SimonG. All Rights Reserved.
+
+using System;
+using System.Linq;
+using System.Reflection;
+using System.Reflection.Emit;
+using LightweightIocContainer.Exceptions;
+using LightweightIocContainer.Factories;
+using LightweightIocContainer.Interfaces;
+using LightweightIocContainer.Interfaces.Factories;
+using LightweightIocContainer.Interfaces.Registrations;
+
+namespace LightweightIocContainer.Registrations
+{
+ ///
+ /// The registration that is used to register an abstract typed factory
+ ///
+ /// The type of the abstract typed factory
+ public class TypedFactoryRegistration : ITypedFactoryRegistration
+ {
+ private readonly IInjectorContainer _container;
+
+ public TypedFactoryRegistration(Type factoryType, IInjectorContainer container)
+ {
+ _container = container;
+
+ InterfaceType = factoryType;
+ Name = $"{InterfaceType.Name}";
+
+ CreateFactory();
+ }
+
+ ///
+ /// The name of the
+ ///
+ public string Name { get; }
+
+ ///
+ /// The Type of the abstract typed factory that is registered with this
+ ///
+ public Type InterfaceType { get; }
+
+ ///
+ /// The class that contains the implemented abstract factory of this
+ ///
+ public ITypedFactory Factory { get; private set; }
+
+
+ ///
+ /// Creates the factory from the given abstract factory type
+ ///
+ /// Factory registration is invalid
+ private void CreateFactory()
+ {
+ var createMethods = InterfaceType.GetMethods().Where(m => m.ReturnType != typeof(void)).ToList();
+ if (!createMethods.Any())
+ throw new InvalidFactoryRegistrationException($"Factory {Name} has no create methods.");
+
+ Type type = typeof(TypedFactory<>);
+ Type factory = type.MakeGenericType(InterfaceType);
+
+ Factory = (ITypedFactory) Activator.CreateInstance(factory);
+
+ AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("Factory"), AssemblyBuilderAccess.Run);
+ ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("Factory");
+ TypeBuilder typeBuilder = moduleBuilder.DefineType($"TypedFactory.{InterfaceType.Name}");
+
+ typeBuilder.AddInterfaceImplementation(InterfaceType);
+
+ //add `private readonly IInjectorContainer _container` field
+ FieldBuilder containerFieldBuilder = typeBuilder.DefineField("_container", typeof(IInjectorContainer), FieldAttributes.Private | FieldAttributes.InitOnly);
+
+ //add ctor
+ ConstructorBuilder constructorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, new[] {typeof(IInjectorContainer)});
+ var constructorGenerator = constructorBuilder.GetILGenerator();
+ constructorGenerator.Emit(OpCodes.Ldarg_0);
+ constructorGenerator.Emit(OpCodes.Ldarg_1);
+ constructorGenerator.Emit(OpCodes.Stfld, containerFieldBuilder); //set `_container` field
+ constructorGenerator.Emit(OpCodes.Ret);
+
+ foreach (var createMethod in createMethods)
+ {
+ //create a method that looks like this
+ //public `createMethod.ReturnType` Create(`createMethod.GetParameters()`)
+ //{
+ // return IInjectorContainer.Resolve(`createMethod.ReturnType`, params);
+ //}
+
+ var args = createMethod.GetParameters();
+
+ MethodBuilder methodBuilder = typeBuilder.DefineMethod(createMethod.Name, MethodAttributes.Public | MethodAttributes.Virtual,
+ createMethod.ReturnType, (from arg in args select arg.ParameterType).ToArray());
+ typeBuilder.DefineMethodOverride(methodBuilder, createMethod);
+
+ var generator = methodBuilder.GetILGenerator();
+
+ generator.Emit(OpCodes.Ldarg_0);
+ generator.Emit(OpCodes.Ldfld, containerFieldBuilder);
+ generator.Emit(OpCodes.Ldtoken, createMethod.ReturnType);
+
+ if (args.Any())
+ {
+ generator.Emit(OpCodes.Ldc_I4_S, args.Length + 1);
+ generator.Emit(OpCodes.Newarr, typeof(object));
+
+ for (int i = 0; i < args.Length; i++)
+ {
+ generator.Emit(OpCodes.Dup);
+ generator.Emit(OpCodes.Ldc_I4_S, i);
+ generator.Emit(OpCodes.Ldarg_S, i + 1);
+ generator.Emit(OpCodes.Stelem_Ref);
+ }
+ }
+ else
+ {
+ generator.Emit(OpCodes.Ldc_I4_0);
+ }
+
+ generator.EmitCall(OpCodes.Callvirt, typeof(IInjectorContainer).GetMethod(nameof(IInjectorContainer.Resolve), new[] { typeof(object), typeof(object)}), null);
+ generator.Emit(OpCodes.Ret);
+ }
+
+ Factory.Factory = (TFactory) Activator.CreateInstance(typeBuilder.CreateTypeInfo().AsType(), _container);
+ }
+ }
+}
\ No newline at end of file