public Type CreateInjectorType(InjectorEmitBody data, string uniqueTypeName) { var baseType = typeof(Injector <>).MakeGenericType(data.ContractType); var typeBuilder = _assembly.DefineType(uniqueTypeName, baseType); return(_injectorBuilder.BuildType(typeBuilder, data)); }
public Type GetOrCreateInjectorType(InjectorEmitBody emitBody) { EmitInjectorKey key; var methodEmitBodySet = emitBody.MethodEmitBodySet; if (methodEmitBodySet != null) { var injectedMethods = new MethodInfo[methodEmitBodySet.Length]; for (int i = 0; i < methodEmitBodySet.Length; i++) { var methodEmitBody = methodEmitBodySet[i]; injectedMethods[i] = methodEmitBody.InjectedMethod; } key = new EmitConstructorAndMemberInjectorKey(emitBody.ConstructorEmitBody.InjectedConstructor, injectedMethods); } else { key = new EmitInjectorKey(emitBody.ConstructorEmitBody.InjectedConstructor); } _injectorLock.Enter(); try { Type injectorType; if (_key2Injector.TryGetValue(key, out injectorType)) { return(injectorType); } injectorType = _provider.CreateInjectorType(emitBody, GetUniqueDynamicTypeName()); _key2Injector.Add(key, injectorType); return(injectorType); } finally { _injectorLock.Exit(); } }
static void EmitConstructor(TypeBuilder typeBuilder, InjectorEmitBody emitBody) { ConstructorBuilder ctorBuilder; EmitGenerator gen; var ctorEmitBody = emitBody.ConstructorEmitBody; var methodEmitBodySet = emitBody.MethodEmitBodySet; var baseType = typeBuilder.BaseType; if (baseType == null) { throw new ImpossibleException(); } var baseCtor = baseType.GetConstructor(BaseConstructorFlags, null, Type.EmptyTypes, null); if (baseCtor == null) { throw new ImpossibleException(); } if (ctorEmitBody.DependencyProviders != null && ctorEmitBody.DependencyProviders.Length > 0) { ctorBuilder = methodEmitBodySet != null ? DefineConstructorBuilder(typeBuilder, true, true) : DefineConstructorBuilder(typeBuilder, true, false); gen = ctorBuilder.GetEmitGenerator(); gen.LoadThis(); gen.CallBaseConstructor(baseCtor); ctorEmitBody.EmitConstructorBody(typeBuilder, gen); if (methodEmitBodySet != null) { var memberParameterIndex = 0; for (int i = 0; i < methodEmitBodySet.Length; i++) { methodEmitBodySet[i].EmitConstructorBody(typeBuilder, gen, 2, ref memberParameterIndex); } } gen.Return(); } else { if (methodEmitBodySet != null) { ctorBuilder = DefineConstructorBuilder(typeBuilder, false, true); gen = ctorBuilder.GetEmitGenerator(); gen.LoadThis(); gen.CallBaseConstructor(baseCtor); var memberParameterIndex = 0; for (int i = 0; i < methodEmitBodySet.Length; i++) { methodEmitBodySet[i].EmitConstructorBody(typeBuilder, gen, 1, ref memberParameterIndex); } gen.Return(); } //else //{ // //ctorBuilder = DefineConstructorBuilder(typeBuilder, false, false); // //ctorGenerator = ctorBuilder.GetEmitGenerator(); // //ctorGenerator.LoadThis(); // //ctorGenerator.CallBaseConstructor(baseCtor); //} } }
//const BindingFlags PublicStaticFlags = BindingFlags.Static | BindingFlags.Public; //static readonly ConstructorInfo ObjectCtor; //static readonly MethodInfo GetParametersProperty; //static readonly MethodInfo RedundantParametersProvided; //static EmitInjectorBuilder() //{ // //ObjectCtor = typeof(object).GetConstructor(Type.EmptyTypes); // //GetParametersProperty = typeof(InjectionContext).GetMethod("get_Parameters", PublicInstanceFlags, null, Type.EmptyTypes, null); // //if (GetParametersProperty == null) // // throw new MissingMethodException("The InjectionContext.Parameters property can not be found!"); // //RedundantParametersProvided = typeof(ParameterException).GetMethod( // // "RedundantParametersProvided", PublicStaticFlags, null, new Type[] { typeof(InjectionContext) }, null); // //if (RedundantParametersProvided == null) // // throw new MissingMethodException("The ParameterException.RedundantParametersProvided method can not be found!"); //} public Type BuildType(TypeBuilder typeBuilder, InjectorEmitBody emitBody) { EmitConstructor(typeBuilder, emitBody); EmitExecuteMethod(typeBuilder, emitBody); return(typeBuilder.CreateType()); }
static void EmitExecuteMethod(TypeBuilder typeBuilder, InjectorEmitBody emitBody) { var methodBuilder = DefineExecuteMethodBuilder(typeBuilder, emitBody.ContractType); var gen = methodBuilder.GetEmitGenerator(); var ctorEmitBody = emitBody.ConstructorEmitBody; var methodEmitBodySet = emitBody.MethodEmitBodySet; var baseType = typeBuilder.BaseType; if (baseType == null) { throw new ImpossibleException(); } var injectInstanceIntoContextMethod = baseType.GetMethod("InjectInstanceIntoContext", PrivateInstanceFlags); if (injectInstanceIntoContextMethod == null) { throw new ImpossibleException(); } var instance = gen.DeclareLocal(ctorEmitBody.InjectedConstructor.DeclaringType); #region Create instance //IObjectRegistration p1; //IConfigurationModule p2; //ILifetimeScope p3; //_parameterMerger.Merge(context, out p1, out p2, out p3); //instance = new DummyClass(p1, p2, p3); ctorEmitBody.EmitExecuteMethodBody(gen, instance); #endregion #region InjectInstanceIntoContext(context, instance); gen.LoadThis(); gen.LoadArgument(1); gen.LoadLocal(instance); gen.CallMethod(injectInstanceIntoContextMethod); #endregion #region Property/Method Injection //Parameter parameter; //_f0.CreateObject(context, out parameter); //instance.Parameter = parameter; //ContainerOption option; //_f1.CreateObject(context, out option); //IObjectContainer container; //_f2.CreateObject(context, out container); //instance.SetProperties(option, container); if (methodEmitBodySet != null) { for (int i = 0; i < methodEmitBodySet.Length; i++) { methodEmitBodySet[i].EmitExecuteMethodBody(gen, instance); } } #endregion gen.Return(); }