public static IEnumerable<IDocumentStorage> Build(IDocumentSchema schema, DocumentMapping[] mappings) { // Generate the actual source code var code = GenerateDocumentStorageCode(mappings); var generator = new AssemblyGenerator(); // Tell the generator which other assemblies that it should be referencing // for the compilation generator.ReferenceAssembly(Assembly.GetExecutingAssembly()); generator.ReferenceAssemblyContainingType<NpgsqlConnection>(); generator.ReferenceAssemblyContainingType<QueryModel>(); generator.ReferenceAssemblyContainingType<DbCommand>(); generator.ReferenceAssemblyContainingType<Component>(); generator.ReferenceAssemblyContainingType<DbDataReader>(); mappings.Select(x => x.DocumentType.Assembly).Distinct().Each(assem => generator.ReferenceAssembly(assem)); // build the new assembly -- this will blow up if there are any // compilation errors with the list of errors and the actual code var assembly = generator.Generate(code); return assembly .GetExportedTypes() .Where(x => x.IsConcreteTypeOf<IDocumentStorage>()) .Select(x => BuildStorageObject(schema, mappings, x)); }
public static string GenerateDocumentStorageCode(DocumentMapping[] mappings) { var writer = new SourceWriter(); // TODO -- get rid of the magic strings var namespaces = new List<string> {"System", "Marten", "Marten.Schema", "Marten.Linq", "Marten.Util", "Npgsql", "Remotion.Linq"}; namespaces.AddRange(mappings.Select(x => x.DocumentType.Namespace)); namespaces.Distinct().OrderBy(x => x).Each(x => writer.WriteLine($"using {x};")); writer.BlankLine(); writer.StartNamespace("Marten.GeneratedCode"); mappings.Each(x => { x.GenerateDocumentStorage(writer); writer.BlankLine(); writer.BlankLine(); }); writer.FinishBlock(); var code = writer.Code(); return code; }
public static IEnumerable<IDocumentStorage> Build(IDocumentSchema schema, DocumentMapping[] mappings) { var code = GenerateDocumentStorageCode(mappings); var generator = new AssemblyGenerator(); generator.ReferenceAssembly(Assembly.GetExecutingAssembly()); generator.ReferenceAssemblyContainingType<NpgsqlConnection>(); generator.ReferenceAssemblyContainingType<QueryModel>(); generator.ReferenceAssemblyContainingType<DbCommand>(); generator.ReferenceAssemblyContainingType<Component>(); mappings.Select(x => x.DocumentType.Assembly).Distinct().Each(assem => generator.ReferenceAssembly(assem)); var assembly = generator.Generate(code); return assembly .GetExportedTypes() .Where(x => x.IsConcreteTypeOf<IDocumentStorage>()) .Select(x => { var docType = x.FindInterfaceThatCloses(typeof (IdAssignment<>)).GetGenericArguments().Single(); var mapping = mappings.Single(m => m.DocumentType == docType); var arguments = mapping.IdStrategy.ToArguments().Select(arg => arg.GetValue(schema)).ToArray(); var ctor = x.GetConstructors().Single(); return ctor.Invoke(arguments).As<IDocumentStorage>(); }); }
public static IEnumerable<IDocumentStorage> Build(DocumentMapping[] mappings) { var code = GenerateDocumentStorageCode(mappings); var generator = new AssemblyGenerator(); generator.ReferenceAssembly(Assembly.GetExecutingAssembly()); generator.ReferenceAssemblyContainingType<NpgsqlConnection>(); generator.ReferenceAssemblyContainingType<QueryModel>(); generator.ReferenceAssemblyContainingType<DbCommand>(); generator.ReferenceAssemblyContainingType<Component>(); mappings.Select(x => x.DocumentType.Assembly).Distinct().Each(assem => generator.ReferenceAssembly(assem)); var assembly = generator.Generate(code); return assembly .GetExportedTypes() .Where(x => x.IsConcreteTypeOf<IDocumentStorage>()) .Select(x => Activator.CreateInstance(x).As<IDocumentStorage>()); }
public static IEnumerable<IDocumentStorage> Build(IDocumentSchema schema, DocumentMapping[] mappings) { // Generate the actual source code var code = GenerateDocumentStorageCode(mappings); var generator = new AssemblyGenerator(); // Tell the generator which other assemblies that it should be referencing // for the compilation generator.ReferenceAssembly(Assembly.GetExecutingAssembly()); generator.ReferenceAssemblyContainingType<NpgsqlConnection>(); generator.ReferenceAssemblyContainingType<QueryModel>(); generator.ReferenceAssemblyContainingType<DbCommand>(); generator.ReferenceAssemblyContainingType<Component>(); generator.ReferenceAssemblyContainingType<DbDataReader>(); mappings.Select(x => x.DocumentType.Assembly).Distinct().Each(assem => generator.ReferenceAssembly(assem)); // build the new assembly -- this will blow up if there are any // compilation errors with the list of errors and the actual code var assembly = generator.Generate(code); return assembly .GetExportedTypes() .Where(x => x.IsConcreteTypeOf<IDocumentStorage>()) .Select(x => { var docType = x.FindInterfaceThatCloses(typeof (IdAssignment<>)).GetGenericArguments().Single(); var mapping = mappings.Single(m => m.DocumentType == docType); var arguments = mapping.IdStrategy.ToArguments().Select(arg => arg.GetValue(schema)).ToArray(); var ctor = x.GetConstructors().Single(); return ctor.Invoke(arguments).As<IDocumentStorage>(); }); }
public static string GenerateDocumentStorageCode(DocumentMapping[] mappings) { var writer = new SourceWriter(); // TODO -- get rid of the magic strings var namespaces = new List<string> { "System", "Marten", "Marten.Schema", "Marten.Services", "Marten.Linq", "Marten.Util", "Npgsql", "Remotion.Linq", typeof (NpgsqlDbType).Namespace, typeof (IEnumerable<>).Namespace, typeof(DbDataReader).Namespace, typeof(CancellationToken).Namespace, typeof(Task).Namespace }; namespaces.AddRange(mappings.Select(x => x.DocumentType.Namespace)); namespaces.Distinct().OrderBy(x => x).Each(x => writer.WriteLine($"using {x};")); writer.BlankLine(); writer.StartNamespace("Marten.GeneratedCode"); mappings.Each(x => { GenerateDocumentStorage(x, writer); writer.BlankLine(); writer.BlankLine(); }); writer.FinishBlock(); return writer.Code(); }