向 autofac 注册 saga 存储库时需要一个实体框架示例



公共交通文档有一个NHiberbate的例子,有没有人有同样的例子,但使用实体框架(SagaDbContextFactory,SagaDbContext)而不是NHibernate。

不要忘记注册 saga 存储库(例如 NHibernate)var 映射 = 映射程序集    .获取类型()    .Where(t => t.BaseType != null && t.BaseType.IsGenericType &&        (t.BaseType.GetGenericTypeDefinition() == typeof(SagaClassMapping<>) ||        t.BaseType.GetGenericTypeDefinition() == typeof(ClassMapping<>)))    .ToArray();建筑工人。Register(c => new SqlServerSessionFactoryProvider(connString, mappings).GetSessionFactory())    .As()    .SingleInstance();建筑工人。RegisterGeneric(typeof(NHibernateSagaRepository<>))    .As(typeof(ISagaRepository<>));

我已经像这样注册了我的:

builder.RegisterAssemblyTypes(typeof(SomeType).Assembly).AsImplementedInterfaces().AsSelf(); 
builder.RegisterGeneric(typeof(SagaRepository<,>)).As(typeof(ISagaRepository<,>));
builder.RegisterGeneric(typeof(SagaDbContext<,>));

然后实现了 SagaRepository 接口:

internal class SagaRepository<TSaga, TSagaClassMapping> : EntityFrameworkSagaRepository<TSaga>, ISagaRepository<TSaga, TSagaClassMapping>
    where TSaga : class, ISaga where TSagaClassMapping : SagaClassMapping<TSaga>, new()
{
    public SagaRepository(
        IWorkerConfiguration workerConfiguration)
        : base(() => new SagaDbContext<TSaga, TSagaClassMapping>(workerConfiguration.ConnectionStrings["SagaRepository"]))
    {
    }
}

对于映射,我使用基类:

internal abstract class BaseInstanceStateMap<TInstance> : SagaClassMapping<TInstance>, IInstanceStateMap<TInstance> where TInstance : BaseSagaInstance
{
    protected BaseInstanceStateMap()
    {
        this.Property(x => x.CorrelationId);
        this.Property(x => x.CurrentState).HasMaxLength(64);
        this.Property(x => x.Initiated).HasColumnType("datetime2").IsRequired();
        this.Property(x => x.Created).HasColumnType("datetime2").IsRequired();
        this.Property(x => x.StateChanged).HasColumnType("datetime2").IsOptional();
    }
}

然后,我为每个映射继承它:

internal class ProductIndexingStateMap : BaseInstanceStateMap<ProductIndexingSagaInstance>
{
    public ProductIndexingStateMap()
    {
        this.Property(x => x.ProductId);
        this.Property(x => x.ProductCorrelation);
        this.Property(x => x.EncryptedConnectionString);
    }
}

实际上可以将EntityFrameworkSagaRepository<T>注册为通用,但它需要您注册一个DbContext。如果使用SagaDbContext - 应用程序中不能有多个 saga。唯一的方法是绑定自定义存储库实现并通过泛型类型参数SagaDbContext,这就是@slinzerthegod在他的示例中所做的。

您还可以创建自己的上下文来注册所有类型。例如:

public class AssemblyScanningSagaDbContext : DbContext
{
    readonly Assembly _mappingAssembly;
    public AssemblyScanningSagaDbContext(Assembly mappingAssembly, string nameOrConnectionString)
        : base(nameOrConnectionString)
    {
        _mappingAssembly = mappingAssembly;
    }
    public AssemblyScanningSagaDbContext(Assembly mappingAssembly, ObjectContext objectContext, bool dbContextOwnsObjectContext)
        : base(objectContext, dbContextOwnsObjectContext)
    {
        _mappingAssembly = mappingAssembly;
    }
    public AssemblyScanningSagaDbContext(Assembly mappingAssembly, DbConnection existingConnection, bool contextOwnsConnection)
        : base(existingConnection, contextOwnsConnection)
    {
        _mappingAssembly = mappingAssembly;
    }
    public AssemblyScanningSagaDbContext(Assembly mappingAssembly, string nameOrConnectionString, DbCompiledModel model)
        : base(nameOrConnectionString, model)
    {
        _mappingAssembly = mappingAssembly;
    }
    public AssemblyScanningSagaDbContext(Assembly mappingAssembly, DbConnection existingConnection, DbCompiledModel model, bool contextOwnsConnection)
        : base(existingConnection, model, contextOwnsConnection)
    {
        _mappingAssembly = mappingAssembly;
    }
    protected AssemblyScanningSagaDbContext(Assembly mappingAssembly)
    {
        _mappingAssembly = mappingAssembly;
    }
    protected AssemblyScanningSagaDbContext(Assembly mappingAssembly, DbCompiledModel model)
        : base(model)
    {
        _mappingAssembly = mappingAssembly;
    }
    protected override void OnModelCreating(DbModelBuilder modelBuilder) =>
        modelBuilder.Configurations.AddFromAssembly(_mappingAssembly);
}

如果您有这样的类,则可以执行以下操作:

builder.Register(c => new AssemblyScanningSagaDbContext(typeof(MySagaMapping).Assembly,
    connectionString).As<DbContext>();
builder.RegisterGeneric(typeof(EntityFrameworkSagaRepository<>))
    .As(typeof(ISagaRepository<>))
    .SingleInstance();
builder.RegisterStateMachineSagas(typeof(MySaga).Assembly);

Autofac 能够自动编写工厂委托,并将其注入存储库构造函数。

以下是作为要点的扫描上下文。

相关内容

最新更新