Ejemplo n.º 1
0
        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));
        }
Ejemplo n.º 2
0
        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>();
                });
        }
Ejemplo n.º 3
0
        public void generate_code_on_the_fly_using_source_writer()
        {
            #region sample_using-AssemblyGenerator-with-source-writer
            var generator = new AssemblyGenerator();

            // This is necessary for the compilation to succeed
            // It's exactly the equivalent of adding references
            // to your project
            generator.ReferenceAssembly(typeof(Console).Assembly);
            generator.ReferenceAssembly(typeof(IOperation).Assembly);


            var assembly = generator.Generate(x =>
            {
                x.Namespace("Generated");
                x.StartClass("AddOperator", typeof(IOperation));

                x.Write("BLOCK:public int Calculate(int one, int two)");
                x.Write("return one + two;");
                x.FinishBlock();  // Finish the method

                x.FinishBlock();  // Finish the class
                x.FinishBlock();  // Finish the namespace
            });



            var type      = assembly.GetExportedTypes().Single();
            var operation = (IOperation)Activator.CreateInstance(type);

            var result = operation.Calculate(1, 2);

            #endregion
            result.ShouldBe(3);
        }
Ejemplo n.º 4
0
        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)));
        }
Ejemplo n.º 5
0
        private void compileAssembly(GeneratedAssembly assembly)
        {
            var compiler = new AssemblyGenerator();

            compiler.ReferenceAssembly(typeof(IDocumentStorage <>).Assembly);
            compiler.ReferenceAssembly(_plan.QueryType.Assembly);
            compiler.ReferenceAssembly(_plan.OutputType.Assembly);

            compiler.Compile(assembly);
        }
        public DocumentProvider <T> Generate <T>()
        {
            var assembly = new GeneratedAssembly(new GenerationRules("Marten.Generated"));

            var operations = new DocumentOperations(assembly, _mapping, _options);

            assembly.Namespaces.Add(typeof(CommandExtensions).Namespace);
            assembly.Namespaces.Add(typeof(TenantIdArgument).Namespace);
            assembly.Namespaces.Add(typeof(NpgsqlCommand).Namespace);


            var queryOnly = new DocumentStorageBuilder(_mapping, StorageStyle.QueryOnly, x => x.QueryOnlySelector)
                            .Build(assembly, operations);

            var lightweight = new DocumentStorageBuilder(_mapping, StorageStyle.Lightweight, x => x.LightweightSelector)
                              .Build(assembly, operations);

            var identityMap = new DocumentStorageBuilder(_mapping, StorageStyle.IdentityMap, x => x.IdentityMapSelector)
                              .Build(assembly, operations);

            var dirtyTracking = new DocumentStorageBuilder(_mapping, StorageStyle.DirtyTracking, x => x.DirtyCheckingSelector)
                                .Build(assembly, operations);

            var bulkWriterType = new BulkLoaderBuilder(_mapping).BuildType(assembly);

            var compiler = new AssemblyGenerator();

            compiler.ReferenceAssembly(typeof(IDocumentStorage <>).Assembly);
            compiler.ReferenceAssembly(typeof(T).Assembly);

            compiler.Compile(assembly);

            var slot = new DocumentProvider <T>
            {
                QueryOnly     = (IDocumentStorage <T>)Activator.CreateInstance(queryOnly.CompiledType, _mapping),
                Lightweight   = (IDocumentStorage <T>)Activator.CreateInstance(lightweight.CompiledType, _mapping),
                IdentityMap   = (IDocumentStorage <T>)Activator.CreateInstance(identityMap.CompiledType, _mapping),
                DirtyTracking = (IDocumentStorage <T>)Activator.CreateInstance(dirtyTracking.CompiledType, _mapping),

                Operations        = operations,
                QueryOnlyType     = queryOnly,
                LightweightType   = lightweight,
                IdentityMapType   = identityMap,
                DirtyTrackingType = dirtyTracking
            };

            slot.BulkLoader = _mapping.IsHierarchy()
                ? (IBulkLoader <T>)Activator.CreateInstance(bulkWriterType.CompiledType, slot.QueryOnly, _mapping)
                : (IBulkLoader <T>)Activator.CreateInstance(bulkWriterType.CompiledType, slot.QueryOnly);

            slot.BulkLoaderType = bulkWriterType;

            return(slot);
        }
Ejemplo n.º 7
0
        private AssemblyGenerator buildGenerator(GenerationRules generation)
        {
            var generator = new AssemblyGenerator();

            generator.ReferenceAssembly(GetType().GetTypeInfo().Assembly);
            generator.ReferenceAssembly(typeof(Task).GetTypeInfo().Assembly);

            foreach (var assembly in generation.Assemblies)
            {
                generator.ReferenceAssembly(assembly);
            }

            return(generator);
        }
Ejemplo n.º 8
0
        private AssemblyGenerator buildGenerator(IGenerationConfig generation)
        {
            // TODO -- should probably do a lot more here. See GH-6
            var generator = new AssemblyGenerator();

            generator.ReferenceAssembly(GetType().GetTypeInfo().Assembly);
            generator.ReferenceAssembly(typeof(Task).GetTypeInfo().Assembly);

            foreach (var assembly in generation.Assemblies)
            {
                generator.ReferenceAssembly(assembly);
            }

            return(generator);
        }
Ejemplo n.º 9
0
        internal GeneratedAssembly Compile(DocumentStore store)
        {
            _assembly = new GeneratedAssembly(new GenerationRules("Marten.Generated"));

            _assembly.Generation.Assemblies.Add(GetType().Assembly);
            _assembly.Generation.Assemblies.AddRange(_applyMethods.ReferencedAssemblies());
            _assembly.Generation.Assemblies.AddRange(_createMethods.ReferencedAssemblies());
            _assembly.Generation.Assemblies.AddRange(_shouldDeleteMethods.ReferencedAssemblies());

            _assembly.Namespaces.Add("System.Linq");

            _isAsync = _createMethods.IsAsync || _applyMethods.IsAsync;

            _aggregateMapping = store.Storage.MappingFor(typeof(T));
            _storageType      = typeof(IDocumentStorage <,>).MakeGenericType(typeof(T), _aggregateMapping.IdType);


            // TODO -- Validate the id strategy for the mapping
            // against the aggregation setup


            buildLiveAggregationType();
            buildInlineAggregationType();
            buildAsyncDaemonAggregation();

            var assemblyGenerator = new AssemblyGenerator();

            assemblyGenerator.ReferenceAssembly(typeof(IMartenSession).Assembly);
            assemblyGenerator.Compile(_assembly);

            return(_assembly);
        }
Ejemplo n.º 10
0
        internal void Compile()
        {
            _assembly = new GeneratedAssembly(new GenerationRules("Marten.Generated"));

            _assembly.Generation.Assemblies.Add(GetType().Assembly);
            _assembly.Generation.Assemblies.AddRange(_projectMethods.ReferencedAssemblies());
            _assembly.Generation.Assemblies.AddRange(_createMethods.ReferencedAssemblies());

            _assembly.Namespaces.Add("System.Linq");

            _isAsync = _createMethods.IsAsync || _projectMethods.IsAsync;

            var baseType = _isAsync ? typeof(AsyncEventProjection <>) : typeof(SyncEventProjection <>);

            baseType    = baseType.MakeGenericType(GetType());
            _inlineType = _assembly.AddType(GetType().Name.Sanitize() + "GeneratedInlineProjection", baseType);

            var method = _inlineType.MethodFor("ApplyEvent");

            method.DerivedVariables.Add(new Variable(GetType(), "Projection"));

            var eventHandling = MethodCollection.AddEventHandling(null, null, _createMethods, _projectMethods);

            method.Frames.Add(eventHandling);

            var assemblyGenerator = new AssemblyGenerator();

            assemblyGenerator.ReferenceAssembly(typeof(IMartenSession).Assembly);
            assemblyGenerator.Compile(_assembly);
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Generate a new method for the basic base class. The base class "TObject" should
        /// only have a single declared method
        /// </summary>
        /// <param name="configuration"></param>
        /// <param name="rules"></param>
        /// <typeparam name="TObject"></typeparam>
        /// <returns></returns>
        private static CodegenResult <TObject> ForBaseOf <TObject>(Action <GeneratedType, GeneratedMethod> configuration)
        {
            if (typeof(TObject).GetMethods().Length != 1)
            {
                throw new ArgumentOutOfRangeException(nameof(TObject), "The supplied base type or interface can only have exactly one declared method");
            }

            var rules    = Builder.Rules();
            var assembly = new GeneratedAssembly(rules);

            var generatedType = assembly.AddType("Tests", "GeneratedType", typeof(TObject));

            var method = generatedType.Methods.Single();

            configuration(generatedType, method);

            var generator = new AssemblyGenerator(new NullLogger <AssemblyGenerator>(), new InMemoryOnlyCompileStrategy(new NullLogger <InMemoryOnlyCompileStrategy>()));

            if (typeof(TObject).IsGenericType)
            {
                foreach (var genericTypeArgument in typeof(TObject).GenericTypeArguments)
                {
                    generator.ReferenceAssembly(genericTypeArgument.Assembly);
                }
            }

            assembly.CompileAll(generator);

            return(new CodegenResult <TObject>(generatedType.CreateInstance <TObject>(), generatedType.SourceCode));
        }
Ejemplo n.º 12
0
        public void say_hello()
        {
            var generator = new AssemblyGenerator();

            generator.ReferenceAssembly(typeof(IGreeter).Assembly);

            var assembly = generator.Generate(w =>
            {
                w.Write(@"


public class HelloWorld : LamarCompiler.Testing.Samples.IGreeter
{
    public string Greetings()
    {
        return ""Hello NDC London!"";
    }
}
");
            });

            var greeter = (IGreeter)Activator.CreateInstance(assembly.GetExportedTypes().Single());


            _output.WriteLine(greeter.Greetings());
        }
        public static (EventDocumentStorage, string) GenerateStorage(StoreOptions options)
        {
            var assembly = new GeneratedAssembly(new GenerationRules(SchemaConstants.MartenGeneratedNamespace));

            assembly.ReferenceAssembly(typeof(EventGraph).Assembly);

            var builderType = assembly.AddType(EventDocumentStorageTypeName, typeof(EventDocumentStorage));

            buildSelectorMethods(options, builderType);

            var appendType = buildAppendEventOperation(options.EventGraph, assembly);

            builderType.MethodFor(nameof(EventDocumentStorage.AppendEvent))
            .Frames.Code($"return new Marten.Generated.AppendEventOperation(stream, e);");

            var insertType = buildInsertStream(builderType, assembly, options.EventGraph);

            var streamQueryHandlerType = buildStreamQueryHandlerType(options.EventGraph, assembly);

            buildQueryForStreamMethod(options.EventGraph, builderType);

            var updateType = buildUpdateStreamVersion(builderType, assembly, options.EventGraph);


            var compiler = new AssemblyGenerator();

            compiler.ReferenceAssembly(typeof(IMartenSession).Assembly);
            compiler.Compile(assembly);


            var writer = new StringWriter();

            writer.WriteLine($"    // {streamQueryHandlerType.TypeName}");
            writer.WriteLine(streamQueryHandlerType.SourceCode);
            writer.WriteLine();

            writer.WriteLine($"    // {insertType.TypeName}");
            writer.WriteLine(insertType.SourceCode);
            writer.WriteLine();

            writer.WriteLine($"    // {appendType.TypeName}");
            writer.WriteLine(appendType.SourceCode);
            writer.WriteLine();

            writer.WriteLine($"    // {updateType.TypeName}");
            writer.WriteLine(updateType.SourceCode);
            writer.WriteLine();

            writer.WriteLine($"    // {builderType.TypeName}");
            writer.WriteLine(builderType.SourceCode);
            writer.WriteLine();



            var code = writer.ToString();

            var storage = (EventDocumentStorage)Activator.CreateInstance(builderType.CompiledType, options);

            return(storage, code);
        }
Ejemplo n.º 14
0
        public static EventDocumentStorage GenerateStorage(StoreOptions options)
        {
            var assembly = new GeneratedAssembly(new GenerationRules("Marten.Generated"));

            assembly.ReferenceAssembly(typeof(EventGraph).Assembly);

            var builderType = assembly.AddType("GeneratedEventDocumentStorage", typeof(EventDocumentStorage));

            buildSelectorMethods(options, builderType);

            buildAppendEventOperation(options.Events, assembly);

            builderType.MethodFor(nameof(EventDocumentStorage.AppendEvent))
            .Frames.Code($"return new Marten.Generated.AppendEventOperation(stream, e);");

            buildInsertStream(builderType, assembly, options.Events);

            var streamQueryHandlerType = buildStreamQueryHandlerType(options.Events, assembly);

            buildQueryForStreamMethod(options.Events, builderType);

            buildUpdateStreamVersion(builderType, assembly, options.Events);


            var compiler = new AssemblyGenerator();

            compiler.ReferenceAssembly(typeof(IMartenSession).Assembly);
            compiler.Compile(assembly);

            var code = streamQueryHandlerType.SourceCode;

            return((EventDocumentStorage)Activator.CreateInstance(builderType.CompiledType, options));
        }
        public static (EventDocumentStorage, string) GenerateStorage(StoreOptions options)
        {
            var assembly    = new GeneratedAssembly(new GenerationRules(SchemaConstants.MartenGeneratedNamespace));
            var builderType = AssembleTypes(options, assembly);


            var compiler = new AssemblyGenerator();

            compiler.ReferenceAssembly(typeof(IMartenSession).Assembly);
            compiler.Compile(assembly);


            var writer = new StringWriter();

            foreach (var generatedType in assembly.GeneratedTypes)
            {
                writer.WriteLine($"    // {generatedType.TypeName}");
                writer.WriteLine(generatedType.SourceCode);
                writer.WriteLine();
            }



            var code = writer.ToString();

            var storage = (EventDocumentStorage)Activator.CreateInstance(builderType.CompiledType, options);

            return(storage, code);
        }
Ejemplo n.º 16
0
        public void generate_code_on_the_fly()
        {
            #region sample_using-AssemblyGenerator
            var generator = new AssemblyGenerator();

            // This is necessary for the compilation to succeed
            // It's exactly the equivalent of adding references
            // to your project
            generator.ReferenceAssembly(typeof(Console).Assembly);
            generator.ReferenceAssembly(typeof(IOperation).Assembly);

            // Compile and generate a new .Net Assembly object
            // in memory
            var assembly = generator.Generate(@"
using LamarCompiler.Testing.Samples;

namespace Generated
{
    public class AddOperator : IOperation
    {
        public int Calculate(int one, int two)
        {
            return one + two;
        }
    }
}
");

            // Find the new type we generated up above
            var type = assembly.GetExportedTypes().Single();

            // Use Activator.CreateInstance() to build an object
            // instance of our new class, and cast it to the
            // IOperation interface
            var operation = (IOperation)Activator.CreateInstance(type);

            // Use our new type
            var result = operation.Calculate(1, 2);

            #endregion
            result.ShouldBe(3);
        }
Ejemplo n.º 17
0
        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>());
        }
Ejemplo n.º 18
0
        public static IEnumerable<IDocumentStorage> Build(IDocumentSchema schema, IDocumentMapping[] 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.ToArguments().Select(arg => arg.GetValue(schema)).ToArray();

                    var ctor = x.GetConstructors().Single();

                    return ctor.Invoke(arguments).As<IDocumentStorage>();
                });
        }
Ejemplo n.º 19
0
        public static IEnumerable <IDocumentStorage> Build(IDocumentSchema schema, IDocumentMapping[] 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.ToArguments().Select(arg => arg.GetValue(schema)).ToArray();

                var ctor = x.GetConstructors().Single();

                return ctor.Invoke(arguments).As <IDocumentStorage>();
            }));
        }
Ejemplo n.º 20
0
        internal static ILiveAggregator <T> Build <T>(StoreOptions options)
        {
            var mapping = options.Storage.MappingFor(typeof(T));

            var assembly = new GeneratedAssembly(new GenerationRules("Marten.Generated"));

            var applyMethods = new ApplyMethodCollection(typeof(T), typeof(T));

            // TODO -- this doesn't do very much right now.
            var createMethods = new CreateMethodCollection(typeof(T), typeof(T));

            assembly.Generation.Assemblies.Add(typeof(IMartenSession).Assembly);
            assembly.Generation.Assemblies.AddRange(applyMethods.ReferencedAssemblies());
            assembly.Generation.Assemblies.AddRange(createMethods.ReferencedAssemblies());

            var isAsync = applyMethods.IsAsync;

            assembly.Namespaces.Add("System.Linq");

            var liveBaseType = isAsync
                ? typeof(AsyncLiveAggregatorBase <>)
                : typeof(SyncLiveAggregatorBase <>);

            liveBaseType = liveBaseType.MakeGenericType(typeof(T));

            var liveType = assembly.AddType(typeof(T).NameInCode().Sanitize() + "LiveAggregation", liveBaseType);

            var overrideMethodName = isAsync ? "BuildAsync" : "Build";
            var buildMethod        = liveType.MethodFor(overrideMethodName);

            // TODO -- use constructor functions later
            // TODO -- use static Create() methods
            // TODO -- validate that there is some way to create the aggregate
            buildMethod.Frames.Code("if (!events.Any()) return null;");
            buildMethod.Frames.Add(new CallCreateAggregateFrame(createMethods));
            buildMethod.Frames.Add(new CallApplyAggregateFrame(applyMethods)
            {
                InsideForEach = true
            });

            buildMethod.Frames.Return(typeof(T));

            createMethods.BuildCreateMethod(liveType, mapping);
            applyMethods.BuildApplyMethod(liveType, mapping);

            var assemblyGenerator = new AssemblyGenerator();

            assemblyGenerator.ReferenceAssembly(typeof(IMartenSession).Assembly);
            assemblyGenerator.Compile(assembly);

            return((ILiveAggregator <T>)Activator.CreateInstance(liveType.CompiledType));
        }
Ejemplo n.º 21
0
        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>()));
        }
        private void compileAssembly(GeneratedAssembly assembly)
        {
            var compiler = new AssemblyGenerator();

            foreach (var referencedAssembly in walkReferencedAssemblies(
                         typeof(IDocumentStorage <>),
                         _plan.QueryType,
                         _plan.OutputType))
            {
                compiler.ReferenceAssembly(referencedAssembly);
            }

            compiler.Compile(assembly);
        }
Ejemplo n.º 23
0
        /// <summary>
        ///     Only for testing support
        /// </summary>
        /// <param name="options"></param>
        /// <returns></returns>
        public static EventDocumentStorage GenerateStorage(StoreOptions options)
        {
            var assembly =
                new GeneratedAssembly(new GenerationRules(SchemaConstants.MartenGeneratedNamespace + ".EventStore"));
            var builderType = AssembleTypes(options, assembly);


            var compiler = new AssemblyGenerator();

            compiler.ReferenceAssembly(typeof(IMartenSession).Assembly);
            compiler.Compile(assembly);


            return((EventDocumentStorage)Activator.CreateInstance(builderType.CompiledType, options));
        }
        internal GeneratedAssembly Compile(StoreOptions options)
        {
            var assembly = new GeneratedAssembly(new GenerationRules(SchemaConstants.MartenGeneratedNamespace));

            AssembleTypes(assembly, options);

            var assemblyGenerator = new AssemblyGenerator();

            assemblyGenerator.ReferenceAssembly(typeof(IMartenSession).Assembly);
            assemblyGenerator.Compile(assembly);

            _liveType   = _liveGeneratedType.CompiledType;
            _inlineType = _inlineGeneratedType.CompiledType;

            return(assembly);
        }
Ejemplo n.º 25
0
    public void generate_a_small_class()
    {
        var code = @"
using System;
using Marten.Testing;


namespace RoslynGenerationSpike
{
    public class Writer : IMessageWriter
    {
        public void WriteMessages()
        {
            Console.WriteLine('What is this?');
            Console.WriteLine('Dynamic Code?');
            Console.WriteLine('Really?');
        }
    }
}
".Replace("'", "\"");


        // New helper for this mess called AssemblyGenerator
        var builder = new AssemblyGenerator();


        // you might need to help it out w/ references
        builder.ReferenceAssembly(Assembly.GetExecutingAssembly());

        // Make the new Assembly
        var assembly = builder.Generate(code);

        // Do stuff with it
        var writerType = assembly.GetExportedTypes().Single();
        var writer = Activator.CreateInstance(writerType).As<IMessageWriter>();

        writer.WriteMessages();
        writer.WriteMessages();
        writer.WriteMessages();
        writer.WriteMessages();
        writer.WriteMessages();
        writer.WriteMessages();
        writer.WriteMessages();
    }
Ejemplo n.º 26
0
    public void generate_a_small_class()
    {
        var code = @"
using System;
using Marten.Testing;


namespace RoslynGenerationSpike
{
    public class Writer : IMessageWriter
    {
        public void WriteMessages()
        {
            Console.WriteLine('What is this?');
            Console.WriteLine('Dynamic Code?');
            Console.WriteLine('Really?');
        }
    }
}
".Replace("'", "\"");


        // New helper for this mess called AssemblyGenerator
        var builder = new AssemblyGenerator();


        // you might need to help it out w/ references
        builder.ReferenceAssembly(Assembly.GetExecutingAssembly());

        // Make the new Assembly
        var assembly = builder.Generate(code);

        // Do stuff with it
        var writerType = assembly.GetExportedTypes().Single();
        var writer     = Activator.CreateInstance(writerType).As <IMessageWriter>();

        writer.WriteMessages();
        writer.WriteMessages();
        writer.WriteMessages();
        writer.WriteMessages();
        writer.WriteMessages();
        writer.WriteMessages();
        writer.WriteMessages();
    }
Ejemplo n.º 27
0
        internal GeneratedAssembly Compile(StoreOptions options)
        {
            _assembly = new GeneratedAssembly(new GenerationRules("Marten.Generated"));

            _assembly.Generation.Assemblies.Add(GetType().Assembly);
            _assembly.Generation.Assemblies.Add(typeof(T).Assembly);
            _assembly.Generation.Assemblies.AddRange(_applyMethods.ReferencedAssemblies());
            _assembly.Generation.Assemblies.AddRange(_createMethods.ReferencedAssemblies());
            _assembly.Generation.Assemblies.AddRange(_shouldDeleteMethods.ReferencedAssemblies());

            _assembly.Namespaces.Add("System");
            _assembly.Namespaces.Add("System.Linq");

            _isAsync = _createMethods.IsAsync || _applyMethods.IsAsync;

            _aggregateMapping = options.Storage.MappingFor(typeof(T));


            if (_aggregateMapping.IdMember == null)
            {
                // TODO -- possibly try to relax this!!!
                throw new InvalidDocumentException(
                          $"No identity property or field can be determined for the aggregate '{typeof(T).FullNameInCode()}', but one is required to be used as an aggregate in projections");
            }

            _storageType = typeof(IDocumentStorage <,>).MakeGenericType(typeof(T), _aggregateMapping.IdType);


            // TODO -- Validate the id strategy for the mapping
            // against the aggregation setup


            buildLiveAggregationType();
            buildInlineAggregationType();

            var assemblyGenerator = new AssemblyGenerator();

            assemblyGenerator.ReferenceAssembly(typeof(IMartenSession).Assembly);
            assemblyGenerator.Compile(_assembly);

            Debug.WriteLine(_liveType.SourceCode);

            return(_assembly);
        }
Ejemplo n.º 28
0
        public DocumentProvider <T> Generate <T>()
        {
            var assembly = new GeneratedAssembly(new GenerationRules(SchemaConstants.MartenGeneratedNamespace));

            var operations = new DocumentOperations(assembly, _mapping, _options);

            assembly.Namespaces.Add(typeof(CommandExtensions).Namespace);
            assembly.Namespaces.Add(typeof(Weasel.Core.CommandExtensions).Namespace);
            assembly.Namespaces.Add(typeof(TenantIdArgument).Namespace);
            assembly.Namespaces.Add(typeof(NpgsqlCommand).Namespace);


            var queryOnly = new DocumentStorageBuilder(_mapping, StorageStyle.QueryOnly, x => x.QueryOnlySelector)
                            .Build(assembly, operations);

            var lightweight = new DocumentStorageBuilder(_mapping, StorageStyle.Lightweight, x => x.LightweightSelector)
                              .Build(assembly, operations);

            var identityMap = new DocumentStorageBuilder(_mapping, StorageStyle.IdentityMap, x => x.IdentityMapSelector)
                              .Build(assembly, operations);

            var dirtyTracking = new DocumentStorageBuilder(_mapping, StorageStyle.DirtyTracking, x => x.DirtyCheckingSelector)
                                .Build(assembly, operations);

            var bulkWriterType = new BulkLoaderBuilder(_mapping).BuildType(assembly);

            var compiler = new AssemblyGenerator();

            var types = new[]
            {
                typeof(IDocumentStorage <>),
                typeof(T),
            };

            foreach (var referencedAssembly in WalkReferencedAssemblies.ForTypes(types))
            {
                compiler.ReferenceAssembly(referencedAssembly);
            }

            var providerType = assembly.AddType(ProviderName,
                                                typeof(DocumentProvider <>).MakeGenericType(_mapping.DocumentType));

            providerType.AllInjectedFields.Clear();

            providerType.AllInjectedFields.Add(new InjectedField(typeof(DocumentMapping), "mapping"));

            var bulkWriterArgType = typeof(IBulkLoader <>).MakeGenericType(_mapping.DocumentType);
            var bulkWriterArgs    = $"new {queryOnly.TypeName}(mapping)";

            if (bulkWriterType.AllInjectedFields.Count == 2)
            {
                bulkWriterArgs += ", mapping";
            }

            var bulkWriterCode = $"new {bulkWriterType.TypeName}({bulkWriterArgs})";

            providerType.BaseConstructorArguments[0] = new Variable(bulkWriterArgType, bulkWriterCode);


            providerType.BaseConstructorArguments[1] = new CreateFromDocumentMapping(_mapping, typeof(IDocumentStorage <>), queryOnly);
            providerType.BaseConstructorArguments[2] = new CreateFromDocumentMapping(_mapping, typeof(IDocumentStorage <>), lightweight);
            providerType.BaseConstructorArguments[3] = new CreateFromDocumentMapping(_mapping, typeof(IDocumentStorage <>), identityMap);
            providerType.BaseConstructorArguments[4] = new CreateFromDocumentMapping(_mapping, typeof(IDocumentStorage <>), dirtyTracking);


            try
            {
                compiler.Compile(assembly);
            }
            catch (Exception e)
            {
                if (e.Message.Contains("is inaccessible due to its protection level"))
                {
                    throw new InvalidOperationException($"Requested document type '{_mapping.DocumentType.FullNameInCode()}' must be either scoped as 'public' or the assembly holding it must use the {nameof(InternalsVisibleToAttribute)} pointing to 'Marten.Generated'", e);
                }

                throw;
            }

            return((DocumentProvider <T>)Activator.CreateInstance(providerType.CompiledType, _mapping));
        }
        public DocumentProvider <T> Generate <T>()
        {
            var assembly = new GeneratedAssembly(new GenerationRules("Marten.Generated"));

            var operations = new DocumentOperations(assembly, _mapping, _options);

            assembly.Namespaces.Add(typeof(CommandExtensions).Namespace);
            assembly.Namespaces.Add(typeof(TenantIdArgument).Namespace);
            assembly.Namespaces.Add(typeof(NpgsqlCommand).Namespace);


            var queryOnly = new DocumentStorageBuilder(_mapping, StorageStyle.QueryOnly, x => x.QueryOnlySelector)
                            .Build(assembly, operations);

            var lightweight = new DocumentStorageBuilder(_mapping, StorageStyle.Lightweight, x => x.LightweightSelector)
                              .Build(assembly, operations);

            var identityMap = new DocumentStorageBuilder(_mapping, StorageStyle.IdentityMap, x => x.IdentityMapSelector)
                              .Build(assembly, operations);

            var dirtyTracking = new DocumentStorageBuilder(_mapping, StorageStyle.DirtyTracking, x => x.DirtyCheckingSelector)
                                .Build(assembly, operations);

            var bulkWriterType = new BulkLoaderBuilder(_mapping).BuildType(assembly);

            var compiler = new AssemblyGenerator();

            compiler.ReferenceAssembly(typeof(IDocumentStorage <>).Assembly);
            compiler.ReferenceAssembly(typeof(T).Assembly);

            try
            {
                compiler.Compile(assembly);
            }
            catch (Exception e)
            {
                if (e.Message.Contains("is inaccessible due to its protection level"))
                {
                    throw new InvalidOperationException($"Requested document type '{_mapping.DocumentType.FullNameInCode()}' must be either scoped as 'public' or the assembly holding it must use the {nameof(InternalsVisibleToAttribute)} pointing to 'Marten.Generated'", e);
                }

                throw;
            }

            var slot = new DocumentProvider <T>
            {
                QueryOnly     = (IDocumentStorage <T>)Activator.CreateInstance(queryOnly.CompiledType, _mapping),
                Lightweight   = (IDocumentStorage <T>)Activator.CreateInstance(lightweight.CompiledType, _mapping),
                IdentityMap   = (IDocumentStorage <T>)Activator.CreateInstance(identityMap.CompiledType, _mapping),
                DirtyTracking = (IDocumentStorage <T>)Activator.CreateInstance(dirtyTracking.CompiledType, _mapping),

                Operations        = operations,
                QueryOnlyType     = queryOnly,
                LightweightType   = lightweight,
                IdentityMapType   = identityMap,
                DirtyTrackingType = dirtyTracking
            };

            slot.BulkLoader = _mapping.IsHierarchy()
                ? (IBulkLoader <T>)Activator.CreateInstance(bulkWriterType.CompiledType, slot.QueryOnly, _mapping)
                : (IBulkLoader <T>)Activator.CreateInstance(bulkWriterType.CompiledType, slot.QueryOnly);

            slot.BulkLoaderType = bulkWriterType;

            return(slot);
        }