private IDictionary <string, Binding> ProcessCompleteModule( ModuleGenerator moduleGenerator, bool ignoreCompletenessErrors) { var bindings = new Dictionary <string, Binding>(StringComparer.Ordinal); var overrides = new Dictionary <string, Binding>(StringComparer.Ordinal); var allModules = new Dictionary <string, ModuleGenerator>(StringComparer.Ordinal); var hasError = false; GatherIncludedModules(moduleGenerator, allModules, new Stack <string>()); var resolver = new Resolver(null, loader, errors => { if (ignoreCompletenessErrors) { return; } hasError = true; foreach (var e in errors) { errorReporter.LogError(e); } }); foreach (var module in allModules.Values) { // Request entry-point bindings var addTo = module.IsOverride ? overrides : bindings; foreach (var injectType in module.Injects) { var key = injectType.Resolve().IsInterface ? CompilerKeys.ForType(injectType) : CompilerKeys.GetMemberKey(injectType); resolver.RequestBinding(key, module.ModuleType.FullName, false, true); } foreach (var providerGenerator in module.ProviderGenerators) { var binding = new CompilerProvidesBinding(providerGenerator); if (addTo.ContainsKey(binding.ProviderKey)) { var message = "Duplicate bindings for {0} in {1}{2}."; var addendum = module.IsOverride ? "overriding module " : string.Empty; throw new ValidationException(string.Format (message, binding.ProviderKey, addendum, module.ModuleType.FullName)); } switch (providerGenerator.ProvidesType) { case ProvidesType.Default: addTo.Add(binding.ProviderKey, binding); break; case ProvidesType.Set: var setKey = CompilerKeys.GetSetKey(binding.ProviderKey); CompilerSetBinding.Add(addTo, setKey, binding); break; default: throw new ArgumentException("Unknown ProvidesType value: " + providerGenerator.ProvidesType); } } } resolver.InstallBindings(bindings); resolver.InstallBindings(overrides); var allBindings = resolver.ResolveAllBindings(); return(!hasError ? allBindings : null); }
private void EmitGetBindings(TypeDefinition runtimeModule) { /** * public override void GetBindings(Dictionary<string, Binding> bindings) * { * var module = this.Module; * bindings.Add("keyof binding0", new ProviderBinding0(module)); * ... * bindings.Add("keyof bindingN", new ProviderBindingN(module)); * } */ var getBindings = new MethodDefinition( "GetBindings", MethodAttributes.Public | MethodAttributes.Virtual, References.Void); var vModule = new VariableDefinition("module", importedModuleType); getBindings.Body.Variables.Add(vModule); getBindings.Body.InitLocals = true; getBindings.Parameters.Add(new ParameterDefinition(References.DictionaryOfStringToBinding)); var il = getBindings.Body.GetILProcessor(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Callvirt, References.RuntimeModule_ModuleGetter); il.Emit(OpCodes.Castclass, importedModuleType); il.Emit(OpCodes.Stloc, vModule); foreach (var binding in ProviderGenerators) { switch (binding.ProvidesType) { case ProvidesType.Default: il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Ldstr, binding.Key); il.Emit(OpCodes.Ldloc, vModule); il.Emit(OpCodes.Newobj, binding.GeneratedCtor); il.Emit(OpCodes.Callvirt, References.DictionaryOfStringToBinding_Add); break; case ProvidesType.Set: var addMethodRef = new GenericInstanceMethod(References.SetBindings_AddOfT); addMethodRef.GenericArguments.Add(binding.ProviderMethod.ReturnType); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Ldstr, CompilerKeys.GetSetKey(binding.Key)); il.Emit(OpCodes.Ldloc, vModule); il.Emit(OpCodes.Newobj, binding.GeneratedCtor); il.Emit(OpCodes.Call, addMethodRef); break; default: throw new InvalidOperationException("Unknown ProvidesType value: " + binding.ProvidesType); } } il.Emit(OpCodes.Ret); runtimeModule.Methods.Add(getBindings); }