Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/291.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Wcf Ninject 3.0.0和NServiceBus 3.3.0注入问题_Wcf_Ninject_Nservicebus - Fatal编程技术网

Wcf Ninject 3.0.0和NServiceBus 3.3.0注入问题

Wcf Ninject 3.0.0和NServiceBus 3.3.0注入问题,wcf,ninject,nservicebus,Wcf,Ninject,Nservicebus,我开发了一个小型测试系统来了解NServiceBus。testproject中的类来自使用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.Exten

我开发了一个小型测试系统来了解NServiceBus。testproject中的类来自使用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()));
    }
}
下面是引导程序:

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();
    }
}
公共类WcfServiceBootstrapper:iwanttorunatstart
{
私有只读列表_hosts=new List();
公开募捐
{
var serviceTypes=GetType().Assembly.GetTypes().Where(t=>typeof(IWcfGatewayService).IsAssignableFrom(t)&&&!t.IsAbstract&&!t.IsInterface).ToList();
foreach(从serviceTypes中的serviceType中的var host)让baseAddress=new[]{newURI(string.Format(“http://localhost:8778/omjykonservices/{0},serviceType.Name))}选择新的ServiceHost(serviceType,baseAddress))
{
_hosts.Add(主机);
var serviceMataDatabehaviour=新serviceMataDatabehavior
{
HttpGetEnabled=true,
MetadataExporter={PolicyVersion=PolicyVersion.Policy15}
};
host.Description.Behaviors.Add(serviceMetadataBehaviour);
host.Open();
}
}
公共停车场()
{
foreach(var host in_hosts.Where(host=>host!=null))
{
host.Close();
}
_hosts.Clear();
}
}
我遇到的问题是,当调用Process方法(在WcfGatewayService中)时,它会失败,因为总线属性为null,即没有注入IBus实例。但是,NinjectBuilder的文档(NServiceBus.ObjectBuilder.Ninject)明确指出,对NinjectBuilder的调用将向IoC注册一个IBus实例,即Ninject。既然情况似乎并非如此,我怀疑我一定忽略了什么


有没有人有过这种设置的经验?关于为什么总线属性没有获得IBus注入实例的任何建议?

当命令上有
Bus
属性时,它没有[Inject]属性。OOTB Ninject不会在没有这样标记的情况下注入到属性中(但Windsor会这样做(根据我粗略的记忆,在中阅读了关于它的章节(这是必读)))


如果这不是问题所在,您会发现一些好的老式调试每次都会击败SO或邮件列表:-


要诊断Ninject是否实际用于创建服务,最好添加一个ctor并在其上粘贴一个断点,然后查看调用方是否是Ninject。实现同样目标的另一种方法是实现
IActivation
(或者称为IStart)。或者在您的
配置中添加
OnActivation
子句。问题是您没有使用Ninject.Extension.WCF创建服务主机。您可以通过添加自己的自定义依赖项并声明为属性来验证这一点。即使使用InjectAttribute,它也将始终为null,因为您自己正在实例化服务主机,只需注册服务类型。为了让ninject magic工作,您需要使用ninject.Extension.WCF提供的机制创建主机。例如,请参见:

var yourServiceConfiguration=NinjectWcfConfiguration.Create();
var selfHost=new NinjectSelfHostBootstrapper(
内核
您的服务配置);
selfHost.Start();

然后你可以在公共汽车停下来的时候停车。Ruben的回答是正确的,通常在使用ninject的属性注入时,您必须声明属性上的InjeAttribute。但是用于nservicebus的ninject对象生成器有一种特殊的启发式方法,它允许进行属性注入,而无需声明注入属性。这是为了方便而添加的,因为大多数NSB示例使用属性注入,而没有任何自定义容器声明。我们认为Ninject和NSB也必须支持这一点。

我很好奇为什么您不使用Windsor作为NServiceBus的容器,因为(正如您所说)其他所有东西都已经在使用它了。原因是我已经在很多其他项目中使用Ninject,坦率地说,我非常喜欢它,因此,我决定将其与实验NServiceBus结合使用,我碰巧也喜欢:-)我们可以(面对面)讨论这个问题,例如,如果你愿意,明天;-)你能快点试试构造函数注入吗?它能工作吗?还是有激活异常?丹尼尔,鲁本,谢谢你的回答。我编辑了最初的帖子,因为我遗漏了一个重要的部分,我认为这会阻止构造函数注入。类WcfServiceBootstrapperI我已经尝试在总线属性上使用[Inject]了,但没有成功。鲁本,丹尼尔。可能是在WcfServiceBootstrapper中创建ServiceHosts的方式与此问题有关吗?@norgie我知道如果Ninject正在创建,并且该属性有一个
[Inject]
,它应该可以工作。如果每个服务都有一个.svc文件,则需要将其指向Ninject工厂类以实现这一点。如果没有,你需要找出谁在做
新的
,并与之讨论确保它要求DI容器来做。Hy ruben,这一次你是不对的。ninject生成器注册了一个特殊的启发式,它不需要注入attribute@DanielMarbach酷-我已经习惯了:)现在我们只需要知道为什么/如果Ninject(在.svc文件点中引用我的工厂)谢谢Daniel。我短路Ninject的原因是,我拥有的Wcf扩展版本只支持http,在运行时由NServiceBus托管时会引发异常,如本示例应用程序中所示。所以我忽略了Ninject中Wcf有一个自托管选项的事实。
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();
    }
}
  var yourServiceConfiguration = NinjectWcfConfiguration.Create<YourService, NinjectServiceSelfHostFactory>();

  var selfHost = new NinjectSelfHostBootstrapper(
            kernel, 
            yourServiceConfiguration );
  selfHost.Start();