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); }
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); }
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); }
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); }
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)); }
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); }
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)); }
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); }
/// <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); }
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); }
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); }
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)); }