公共交通文档有一个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 能够自动编写工厂委托,并将其注入存储库构造函数。
以下是作为要点的扫描上下文。