public static void PlasmaRegisterAll(this IMetaWriter writer) { // todo - fetch external references!! var assemblies = AppDomain.CurrentDomain.GetAssemblies() .Where(x => !x.Location.ToLowerInvariant().StartsWith(Path.GetTempPath().ToLowerInvariant()) && !x.FullName.StartsWith("System") && !x.FullName.StartsWith("Microsoft.") && !x.FullName.StartsWith("mscorlib") && !x.FullName.StartsWith("MetaCreator") && !x.FullName.StartsWith("Plasma,") && !x.FullName.StartsWith("Plasma ") && !x.FullName.StartsWith("Accessibility,") #if !NET3 && !x.IsDynamic // not sure #endif ); #if DEBUG foreach (var assembly in assemblies) { writer.WriteLine("// " + assembly.FullName); // + " IsDynamic:" + assembly.IsDynamic + " HostContext:" + assembly.HostContext + " Location:" + assembly.Location); } #endif PlasmaRegisterAssembly(writer, assemblies.ToArray()); }
/// <summary> /// Generate code necessary to prepare registers for working with types collected /// </summary> public override void Write(IMetaWriter writer) { foreach (var kvp in _result) { if (kvp.Value.Res != null) { writer.WriteLine("{2}.Register<{0}, {1}>();", kvp.Key, kvp.Value.Res, typeof(FaceImplRegister)); } else if (kvp.Value.Ex != null) { writer.WriteLine("#warning " + kvp.Value.Ex.Message); writer.WriteLine("/*"); writer.WriteLine(ExceptionAnalyzer.ExceptionDetails(kvp.Value.Ex)); writer.WriteLine("*/"); } } }
public override void Write(IMetaWriter writer) { foreach (var result in _result) { if (result.Value.FactoryCode != null || result.Value.FactoryFactoryCode != null) { writer.WriteLine("{2}.Add<{0}>({1});", result.Key, result.Value.FactoryFactoryCode ?? result.Value.FactoryCode, typeof(TypeFactoryRegister)); } else if (result.Value.Ex != null) { writer.WriteLine("#warning " + result.Value.Ex.Message); writer.WriteLine("/*"); writer.WriteLine(ExceptionAnalyzer.ExceptionDetails(result.Value.Ex)); writer.WriteLine("*/"); } } }
public static void PlasmaRegisterType(this IMetaWriter writer, Type type) { if (PlasmaContainer.IsValidImplementationType(type)) { writer.WriteLine("// " + type.CSharpTypeIdentifier()); _context.Types.Add(type); } }
/// <summary> /// Generate code necessary to prepare registers for working with types collected /// </summary> public override void Write(IMetaWriter writer) { foreach (var type in _result) { if (type.Value) { var plumbingPros = PlasmaContainer.GetPlumbingProperties(type.Key).ToArray(); var plumbingc = ""; foreach (var pi in plumbingPros) { plumbingc += string.Format("\tx.{0} = {1};\r\n", pi.Name, _mining.GetArgument(pi)); } // todo remove extra cast in plumber // todo remove dependancy on 'c' writer.WriteLine(@"{2}.Register<{0}>((c, x)=>{{ {1}}});", type.Key, plumbingc, typeof(TypeAutoPlumberRegister)); } else { writer.WriteLine("{1}.RegisterNone(typeof({0}));", type.Key, typeof(TypeAutoPlumberRegister)); } } }
public void Generate(IMetaWriter writer, Type type) { _writer = writer; _type = type; writer.WriteLine("// iface - " + type.Name); // writer.WriteLine("// all ifaces - " + string.Join(", ", Mining.GetAllIfaces(type).Distinct().Select(x => x.Name))); var members = type.GetMembers(BindingFlags.Public | BindingFlags.Instance).Concat(Mining.GetAllIfaces(type).Distinct().SelectMany(x => x.GetMembers())).ToArray(); // if (!members.Any()) // { // return; // } var names = GetTypeName(type); _typeShortName = names.Name; _typeShortNameGeneric = names.NameGeneric; _typeFullNameGeneric = names.FullNameGeneric; writer.WriteLine("public class {0} : {2} {1}", _typeShortNameGeneric, type.CSharpTypeIdentifier(), string.Format(BaseClass, type.CSharpTypeIdentifier())); writer.WriteLine("{"); BeforeMembers(); var methods = members.Where(x => x.MemberType == MemberTypes.Method).Cast <MethodInfo>().Where(x => !x.IsSpecialName).ToArray(); foreach (var method in methods) { if (methods.Count(x => x.Name == method.Name) > 1 /* && method.ReturnType == typeof(object) */) // todo improve by comparing signature, not just name { writer.Write("\t{0} {4}.{1}{2}({3})", method.ReturnType.CSharpTypeIdentifier(), method.Name, null, string.Join(", ", method.GetParameters().Select(x => x.CSharpTypeIdentifier() + " " + x.Name).ToArray()), method.DeclaringType.CSharpTypeIdentifier()); } else { writer.Write("\tpublic virtual {0} {1}{2}({3})", method.ReturnType.CSharpTypeIdentifier(), method.Name, null, string.Join(", ", method.GetParameters().Select(x => x.CSharpTypeIdentifier() + " " + x.Name).ToArray())); } writer.Write(" { "); WriteMethodBody(method); writer.WriteLine(" }"); } foreach (var eventInfo in members.Where(x => x.MemberType == MemberTypes.Event).Cast <EventInfo>()) { writer.Write("\tpublic virtual event {0} {1}", eventInfo.EventHandlerType.CSharpTypeIdentifier(), eventInfo.Name); writer.Write(" { "); writer.Write(" add { "); WriteEventSubscriber(eventInfo); writer.Write(" }"); writer.Write(" remove { "); WriteEventUnsubscriber(eventInfo); writer.Write(" }"); writer.WriteLine(" }"); } var pros = members.Where(x => x.MemberType == MemberTypes.Property).Cast <PropertyInfo>().ToArray(); foreach (var pro in pros) { var isIndexer = pro.GetIndexParameters().Any(); var indexerParameters = string.Join(", ", pro.GetIndexParameters().Select(x => x.ParameterType.CSharpTypeIdentifier() + " " + x.Name).ToArray()); indexerParameters = indexerParameters.Any() ? " [" + indexerParameters + "]" : null; var indexerArguments = string.Join(", ", pro.GetIndexParameters().Select(x => x.Name).ToArray()); indexerArguments = indexerArguments.Any() ? "[" + indexerArguments + "]" : null; var myProName = isIndexer ? "this" : pro.Name; var orProName = isIndexer ? "" : "." + pro.Name; if (pros.Count(x => x.Name == pro.Name) > 1 /* && pro.PropertyType == typeof(object)*/) // todo improve by comparing signature, not just name. +not just object but all except several obvious cases { writer.Write("\t{0} {3}.{1}{2}", pro.PropertyType.CSharpTypeIdentifier(), myProName, indexerParameters, pro.DeclaringType.CSharpTypeIdentifier()); } else { writer.Write("\tpublic virtual {0} {1}{2}", pro.PropertyType.CSharpTypeIdentifier(), myProName, indexerParameters); } writer.Write(" { "); if (pro.CanRead) { writer.Write(" get { "); if (isIndexer) { WriteIndexerGetter(pro, indexerArguments); } else { WritePropertyGetter(pro); } writer.Write(" }"); } if (pro.CanWrite) { writer.Write(" set { "); if (isIndexer) { WriteIndexerSetter(pro, indexerArguments); } else { WritePropertySetter(pro); } writer.Write(" }"); } writer.WriteLine(" }"); } writer.WriteLine("}"); }
/// <summary> /// Finally write all code /// End your file with that line /// </summary> public static void PlasmaGenerate(this IMetaWriter writer) { #region PREPARE _writerTmp = writer; var ctx = new PlasmaContainer(); // AssemblyAnalyzeCache.LoadAll(writer); AssemblyAnalyzeCache.AnalyzeImpls(); // a set of types that is going to be asked from container var requests = new HashSet <Type>(_context.Types); var requestsProcessed = new HashSet <Type>(); var faceImpls = ctx.Get <FaceImplStrategy>(); var factory = ctx.Get <FactoryStrategy>(); var plumbing = ctx.Get <PlumbingStrategy>(); var miner = ctx.Get <StaticMining>(); miner.RequestByType += Miner_RequestByType; writer.WriteLine("// Analyze..."); while (requests.Count > 0) { _requestsFromMiner.Clear(); // not necessary - just to simplify debugging var fromFace = faceImpls.GetRequests(requests).ToArray(); var fromFact = factory.GetRequests(requests).ToArray(); var fromPlumb = plumbing.GetRequests(requests).ToArray(); foreach (var request in requests) { requestsProcessed.Add(request); } // new requests requests = new HashSet <Type>(fromFace.Concat(fromFact).Concat(fromPlumb).Concat(_requestsFromMiner).Except(requestsProcessed)); writer.WriteLine("// New requests: {0}", string.Join(", ", requests.Select(x => x.CSharpTypeIdentifier()))); } miner.RequestByType -= Miner_RequestByType; writer.WriteLine("// Analyze completed"); #endregion #region Proxy if (_enableProxy) { foreach (var type in _context.Types.Where(x => x.IsInterface)) { _proxyGenerator.Generate(writer, type); // GenerateStub(writer, type); } } #endregion #region Null if (_enableNullObject) { var req = _context.Types.Where(x => x.IsInterface); do { foreach (var type in req.ToArray()) { try { writer.Transactional(w => _nullGenerator.Generate(writer, type)); } catch (Exception ex) { writer.WriteLine("#warning " + ex.Message); writer.WriteLine("/*"); writer.WriteLine(ExceptionAnalyzer.ExceptionDetails(ex)); writer.WriteLine("*/"); } } req = _nullGenerator.RequestedObjects.Except(_nullGenerator.NullObjects).ToArray(); _nullGenerator.RequestedObjects.Clear(); } while (req.Any()); } #endregion writer.WriteLine(@" public static partial class PlasmaRegistration {{ static volatile bool _executed; public static void Run({1}? reflectionPermission = null) {{ if (_executed) {{ return; }} _executed = true; {0}.DefaultReflectionPermission = reflectionPermission ?? {1}.Throw; ", typeof(PlasmaContainer), typeof(ReflectionPermission)); writer.WriteLine(); // ignore tabs #region Factory writer.WriteLine(); writer.WriteLine("// Factory "); factory.Write(writer); #endregion #region face impl writer.WriteLine(); writer.WriteLine("// Iface impl"); faceImpls.Write(writer); #endregion #region plumbers writer.WriteLine(); writer.WriteLine("// Plumbers (Property injectors)"); plumbing.Write(writer); #endregion #region null object register if (_enableNullObject) { foreach (var type in _nullGenerator.NullObjects.Concat(_nullGenerator.ExplicitRequests).Distinct()) { if (type.IsGenericType && type.IsGenericTypeDefinition) { writer.WriteLine(@"Null.RegisterGeneric(typeof({0}), t => typeof ({1}).MakeGenericType(t).GetField(""Instance"").GetValue(null));" , type.CSharpTypeIdentifier(_omitTypeDef), _nullGenerator.GetTypeName(type).FullNameGenericNoT); //typeof (NullEnumerable<>).MakeGenericType(t).GetField("Instance").GetValue(null)); } else { writer.WriteLine("Null.Register<{0}>({1}.Instance);", type, _nullGenerator.GetTypeName(type).FullNameGeneric); } } } #endregion writer.WriteLine(@" } } "); }