如何使用IWantToRunBeforeConfigurationIsFinalized,将属性注入处理程序*并继续使用Nservicebus测试框架?

时间:2015-10-08 20:00:53

标签: autofac nservicebus

Nervicebus 4.6单元测试问题

我最近发现IWantToRunBeforeConfigurationIsFinalized将属性注入处理程序,更改了我的所有服务代码,现在我的所有NserviceBus.Test突然失败。

public void run {
   Configure.Instance.Configurer.ConfigureProperty<MyMessage_Handler>(h => h.MyProperty, "somevalue");
}

当我尝试单元测试时

var message = new MyMessage
{
   ...
   ...
 };

 Test.Handler<MyMessage_Handler>().WithExternalDependencies(m =>
 {
   m.PropertyA = aValue;
   m.PropertyB = bValue;     
 })          
 .ExpectPublish<MyEvent>(m =>
 {
    Assert.That(...);
    return true; 
 })
 .OnMessage<MyMessage>(message);

我收到以下异常

  

TestFixture失败:SetUp:System.InvalidOperationException:不能   配置尚未配置的类型的属性:
  在   NServiceBus.ObjectBuilder.Autofac.AutofacObjectBuilder.ConfigureProperty(类型   组件,字符串属性,对象值)   Y:\ BuildAgent \工作\ 31f8c64a6e8a2d7c的\ src \ NServiceBus.Core \ ObjectBuilder的\ Autofac \ AutofacObjectBuilder.cs:行   114

但是如果我像这样配置总线,则在处理程序上调用configurecomponent。测试框架工作

这是我原来的方法,它工作正常,但我更喜欢IWantToRunBeforeConfigurationIsFinalized的方法来干净地分离逻辑。

 Configure.With()
.DefaultBuilder()
.PurgeOnStartup(false)            
.RunCustomAction(() => Configure.Instance.Configurer.ConfigureComponent<MyMessage_Handler>(DependencyLifecycle.InstancePerUnitOfWork))
.RunCustomAction(() => {                    
  Configure.Instance.Configurer.ConfigureProperty<MyMessage_Handler>(h => h.MyProperty, "myValue");
}
...

如何使用IWantToRunBeforeConfigurationIsFinalized,将属性注入处理程序继续使用Nservicebus测试框架?

1 个答案:

答案 0 :(得分:2)

尝试直接在处理程序上配置属性似乎很奇怪。如果它只需要一个处理程序,那么它应该在该处理程序中处理,也许在该处理程序类中的静态构造函数中处理。

无论如何,当你将类型加载并注册到容器中时,你将自己置于左右,这在NServiceBus的不同版本中并不一定是确定性的,显然不是在处理测试框架。

相反,如果您创建了一个新类,那该怎么办:

public class ReferenceValues
{
    public string MyProperty { get; set; }
}

然后,您可以从端点启动的任何位置正常注册此类型。优选地,作为INeedInitialization,因为大多数可扩展点在NServiceBus 5.x中消失,而INeedInitialization实际上是城里唯一的游戏。

// V4 code
public class SetupReferenceValues : INeedInitialization
{
  public void Init()
  {
    Configure.Component<ReferenceValues>(DependencyLifecycle.SingleInstance)
      .ConfigureProperty(rv => rv.MyProperty, "myValue");
  }
}

然后,在你的处理程序中:

public class MyHandler : IHandleMessages<MyMessage>
{
  public ReferenceValues Values { get; set; }

  public void Handle(MyMessage message)
  {
    Console.WriteLine(Values.MyProperty);
  }
}

我认为这也应该来自测试框架。