我正试图让autofac将一个工厂注入创作的传奇中,而我无法让它发挥作用。我没有把工厂注入消费者的问题所以我知道它已正确注册,所以我假设我没有正确注册传真,而autofac也没有建立起来。
这是我的注册码:
var mapTypes = assembly.GetTypes()
.Where(type => type.Implements(typeof(SagaClassMapping<>)));
builder.Register(context => GetSessionFactory(mapTypes)).AsSelf().SingleInstance();
// register all sagas and consumers
builder.RegisterAssemblyTypes(assembly)
.Where(type => type.IsAssignableTo<ISaga>() || type.IsAssignableTo<IConsumer>())
.AsSelf();
builder
.RegisterGeneric(typeof(NHibernateSagaRepository<>))
.As(typeof(ISagaRepository<>))
.SingleInstance();
builder
.Register(context => ServiceBusFactory.New(sbc =>
{
sbc.UseLog4Net();
var queueUri = new Uri(ConfigurationManager.AppSettings["ReceiveQueue"]);
var scope = context.Resolve<ILifetimeScope>();
sbc.UseRabbitMq(transportConfig =>
transportConfig.ConfigureHost(queueUri, hostConfig =>
{
hostConfig.SetUsername(ConfigurationManager.AppSettings["busUser"]);
hostConfig.SetPassword(ConfigurationManager.AppSettings["busPassword"]);
}));
sbc.ReceiveFrom(queueUri);
sbc.Subscribe(cfg => cfg.LoadFrom(scope));
}))
.SingleInstance();
传奇本身很标准
public class MySaga : SagaStateMachine<MySaga>, ISaga
{
public Guid CorrelationId { get; private set; }
public Func<MyObject> ObjectBuilder { get; set; }
public MySaga() { }
public MySaga(Guid correlationId)
{
CorrelationId = correlationId;
}
Static MySaga()
{
Define(() =>
{ .... }
}
我已经尝试将Func<MyObject>
添加到构造函数中,但它没有被命中,它确实在消费者中工作,因此我知道Autofac可以构建Func<MyObject>
。我也尝试过使用属性注入而没有运气:
builder.RegisterAssemblyTypes(assembly)
.Where(type => type.IsAssignableTo<ISaga>() || type.IsAssignableTo<IConsumer>())
.PropertiesAutowired()
.AsSelf();
和
builder.RegisterType<MySaga>()
.OnActivated(arg => arg.Instance.MyBuilder =
arg.Context.Resolve<Func<MyObject>>())
.AsSelf();
对于我做错的任何帮助都将不胜感激。
我得到了Chris Patterson对masstransit-discuss group的答复,指出我可能做错了。
如果你有依赖关系,Automatonymous是一个更好的选择,因为状态机和状态本身是单独的类。
通过NHibernate注入依赖于水合的类永远不会结束。从NHibernate加载后,有几个辅助类可用于对saga执行属性注入,我认为装饰传奇存储库已在此处发布。
以下是Magnum注入存储库的示例: https://github.com/MassTransit/MassTransit/blob/master/src/MassTransit.Tests/Saga/Injecting_Specs.cs
鉴于它的NHibernate正在保护物体,我应该在那里寻找钩子。我的当前问题有一个解决方法,但如果/当我找到答案时,我会在这里发布答案。
答案 0 :(得分:1)
首先创建一个布线类(属性注入)
public class MySagaRepository<TSaga> : ISagaRepository<TSaga> where TSaga : class, ISaga
{
private ISagaRepository<TSaga> _inner;
private readonly IComponentContext _context;
public MySagaRepository(ISagaRepository<TSaga> inner, IComponentContext context)
{
_inner = inner;
_context = context;
}
public IEnumerable<Action<IConsumeContext<TMessage>>> GetSaga<TMessage>(IConsumeContext<TMessage> context, Guid sagaId, InstanceHandlerSelector<TSaga, TMessage> selector, ISagaPolicy<TSaga, TMessage> policy) where TMessage : class
{
return _inner.GetSaga(context, sagaId, (saga, message) =>
{
_context.InjectProperties(saga);
return selector(saga, message);
}, policy);
}
public IEnumerable<Guid> Find(ISagaFilter<TSaga> filter)
{
return _inner.Find(filter);
}
public IEnumerable<TSaga> Where(ISagaFilter<TSaga> filter)
{
return _inner.Where(filter).Select(x =>
{
_context.InjectProperties<TSaga>(x);
return x;
});
}
public IEnumerable<TResult> Where<TResult>(ISagaFilter<TSaga> filter, Func<TSaga, TResult> transformer)
{
return _inner.Where(filter, x =>
{
_context.InjectProperties(x);
return transformer(x);
});
}
public IEnumerable<TResult> Select<TResult>(Func<TSaga, TResult> transformer)
{
return _inner.Select(x =>
{
_context.InjectProperties(x);
return transformer(x);
});
}
}
然后连线
builder.RegisterGeneric(typeof(NHibernateSagaRepository<>)).Named("innerRepo", typeof(ISagaRepository<>));
builder.RegisterGenericDecorator(typeof(MySagaRepository<>), typeof(ISagaRepository<>), fromKey: "innerRepo");
持久性只是一个问题
public class SagaPersistenceHandler
{
public static ISessionFactory CreateSessionFactory()
{
var provider = new SqlServerSessionFactoryProvider(ConfigurationManager.ConnectionStrings["myConnectionString"].ConnectionString, new[]
{
typeof (MySagaMap)
});
return provider.GetSessionFactory();
}
}
现在连线
builder.Register(c => SagaPersistenceHandler.CreateSessionFactory()).As<ISessionFactory>();
和saga映射到saga(不包括在内)
public MySagaMap()
{
SchemaAction(NHibernate.Mapping.ByCode.SchemaAction.None);
Table("dbo.[tTable]");
Property(x => x.Id);
Property(x => x.CloseDate);
}
}
剩下的就是注册你的传奇
builder.RegisterType<MySaga>().AsSelf();
运作良好(积分归@erikkallen)
答案 1 :(得分:1)
我为Autofac制作了一个适配器来注册和配置MT状态机传奇。
回购是here。
可在nuget.org上找到。
您可以致电:
注册您的消费者和州机器builder.RegisterSagaStateMachines(sagasAssembly); // register all state machines
builder.RegisterConsumers(consumersAssembly); // register consumers (standard MassTransit Autofac integration)
请注意,RegisterConsumers
是标准MassTransit.Autofac
扩展名。
在端点配置中,您需要调用以下配置:
x.ReceiveEndpoint(queueName, c =>
{
c.LoadConsumers(container);
c.LoadStateMachineSagas(container);
});
前提条件是您还必须注册ISagaRepository
实施。