1

masstransit 文档有 NHiberbate 的示例,是否有人有相同的示例,但使用实体框架 (SagaDbContextFactory,SagaDbContext) 而不是 NHibernate

// 不要忘记注册 saga 存储库(NHibernate 的示例)
var mappings = mappingsAssembly
    .GetTypes()
    .Where(t => t.BaseType != null && t.BaseType.IsGenericType &&
        (t.BaseType.GetGenericTypeDefinition() == typeof(SagaClassMapping<>) ||
        t.BaseType.GetGenericTypeDefinition() == typeof(ClassMapping<>)))
    .ToArray();
builder.Register(c => new SqlServerSessionFactoryProvider(connString, mappings).GetSessionFactory())
    .As<ISessionFactory>()
    .SingleInstance();
builder.RegisterGeneric(typeof(NHibernateSagaRepository<>))
    .As(typeof(ISagaRepository<>));
4

2 回答 2

2

我已经这样注册了我的:

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);
    }
}
于 2017-02-16T10:12:17.380 回答
1

您实际上可以注册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 能够自动组合工厂委托并将其注入存储库构造函数。

这是作为 gist 的扫描上下文

于 2017-02-16T13:27:37.823 回答