我开发了一个小型测试系统来了解 NServiceBus。测试项目中的类取自使用 Castle.Windsor 进行依赖注入的生产系统。
除了 Ninject 和 NServiceBus 程序集之外,testproject 还引用了:
Ninject.Extensions.ContextPreservation 3.0.0.0
Ninject.Extensions.Conventions 3.0.0.0
Ninject.Extensions.NamedScope 3.0.0.0
Ninject.Extensions.Wcf 3.0.0.0
Ninject.Web.Common 3.0.0.0
NServiceBus.ObjectBuilder.Ninject 3.3.0.0
这是 NServiceBus 端点配置:
public class EndpointConfig : IConfigureThisEndpoint, AsA_Server, IWantCustomInitialization
{
private IKernel _kernel;
public void Init()
{
_kernel = new StandardKernel(new EndpointModule());
Configure.With()
.NinjectBuilder(_kernel)
.Log4Net()
.XmlSerializer();
}
}
EndpointModule 定义为:
public class EndpointModule : NinjectModule
{
public override void Load()
{
Kernel.Bind(x => x.FromThisAssembly().SelectAllTypes().InheritedFrom<IWcfGatewayService>().BindToSelf().Configure(c => c.InTransientScope()));
}
}
下面是实现 IWcfGatewayService 的类型的示例:
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.PerCall)]
public abstract class WcfGatewayService<TCommand> : IWcfGatewayService where TCommand : ICommand
{
public IBus Bus { get; set; }
public ResponseCode Process(TCommand command)
{
try
{
Bus.SendLocal(command);
return ResponseCode.Sent;
}
catch (Exception)
{
return ResponseCode.Failed;
}
}
}
这是一个实际服务的实现:
public class PlaceOrderCommandService : WcfGatewayService<PlaceOrderCommand>, IPlaceOrderCommandService
{}
和
[ServiceContract]
public interface IPlaceOrderCommandService
{
[OperationContract(Action = "http://tempuri.org/IPlaceOrderCommandService/Process", ReplyAction = "http://tempuri.org/IPlaceOrderCommandService/ProcessResponse")]
ResponseCode Process(PlaceOrderCommand command);
}
这是引导程序:
public class WcfServiceBootstrapper : IWantToRunAtStartup
{
private readonly List<ServiceHostBase> _hosts = new List<ServiceHostBase>();
public void Run()
{
var serviceTypes = GetType().Assembly.GetTypes().Where(t => typeof(IWcfGatewayService).IsAssignableFrom(t) && !t.IsAbstract && !t.IsInterface).ToList();
foreach (var host in from serviceType in serviceTypes let baseAddress = new[] { new Uri(string.Format("http://localhost:8778/omjykonservices/{0}", serviceType.Name)) } select new ServiceHost(serviceType, baseAddress))
{
_hosts.Add(host);
var serviceMetadataBehaviour = new ServiceMetadataBehavior
{
HttpGetEnabled = true,
MetadataExporter = {PolicyVersion = PolicyVersion.Policy15}
};
host.Description.Behaviors.Add(serviceMetadataBehaviour);
host.Open();
}
}
public void Stop()
{
foreach (var host in _hosts.Where(host => host != null))
{
host.Close();
}
_hosts.Clear();
}
}
我遇到的问题是,当调用 Process 方法(在 WcfGatewayService 中)时,它会失败,因为 Bus 属性为空,即没有注入 IBus 实例。但是,NinjectBuilder (NServiceBus.ObjectBuilder.Ninject) 的文档明确指出,对 NinjectBuilder 的调用将向 IoC 注册一个 IBus 实例,即 Ninject。由于情况似乎并非如此,我怀疑我一定忽略了一些东西。
有没有人有过这种设置的经验?关于为什么 Bus 属性没有注入 IBus 实例的任何建议?