使用 Ninject 2 将参数传递给 WCF ServiceHost 类型

Posted

技术标签:

【中文标题】使用 Ninject 2 将参数传递给 WCF ServiceHost 类型【英文标题】:Passing parameters to a WCF ServiceHost type with Ninject 2 【发布时间】:2011-08-09 15:30:25 【问题描述】:

我想使用 Ninject.Wcf 扩展来创建参数化服务主机实例。

例如,我有一个类MyWCFHandler,只有以下构造函数:

public MyWCFHandler(UserManager manager)

  _manager = manager;

但是当我写var myServiceHost = new ServiceHost(typeof(MyWCFHandler)); 时,我无法将依赖对象传递给构造函数。

我不想弄乱像提供的自定义 ServiceHost How do I pass values to the constructor on my wcf service?

我决定采用 Ninject 方式,但无法完全理解如何在我的情况下采取行动。

这是我对 Ninject 中 WCF 扩展的理解:

    在我的项目中引用 Ninject 和 Ninject.Extensions.WCF。

    创建一个继承 Ninject 模块的类并编写如下内容:

    internal class ServiceModule : NinjectModule public override void Load() Bind<IUserManager>().To<UserManager>().WithConstructorParameters(myUserManagerIwantToUseInWCFHandler);

    将使用 new ServiceModule() 初始化的内核添加到 KernelContainer。

    像这样使用 NinjectServiceHost:

    var service = KernelContainer.Kernel.Get<IMyWCFHandler>(); _host = new NinjectServiceHost( service );

我应该在那里准备好打开我的主机。

问题是:

我应该如何将我的构造函数参数传递给 NinjectModule?当我准备好将参数绑定到它时,是否应该创建一个 NinjectModule 实例?如何将它们传递给 Get 方法?

不幸的是,没有一个示例可以简单地显示参数化的 ServiceHost 启动。我什至不在乎我使用的是不是 Ninject。无论哪种解决方案都有一个很好的例子——我很好,因为我只是决定使用什么 IoC 容器。

【问题讨论】:

【参考方案1】:

关于ninject。答案是这取决于您是否需要一个单例服务或每个请求一个新实例。使用单例服务,您可以执行以下操作:

public class TimeServiceModule : NinjectModule

    /// <summary>
    /// Loads the module into the kernel.
    /// </summary>
    public override void Load()
    
        this.Bind<ITimeService>().To<TimeService>();

        this.Bind<ServiceHost>().ToMethod(ctx => ctx.Kernel.Get<NinjectServiceHost>(new ConstructorArgument("singletonInstance", c => c.Kernel.Get<ITimeService>())));
    


internal static class Program

    private static void Main()
    
        var kernel = new StandardKernel(new TimeServiceModule());

        var serviceHost = kernel.Get<ServiceHost>();
        serviceHost.AddServiceEndpoint(typeof(ITimeService), new NetTcpBinding(), "net.tcp://localhost/TimeService");
        try
        
            serviceHost.Open();
        
        finally
        
            serviceHost.Close();
        
    

按请求方式:

public interface IServiceTypeProvider

    /// <summary>
    /// Gets the service types.
    /// </summary>
    /// <value>The service types.</value>
    IEnumerable<Type> Types  get; 


Func<Type, ServiceHost> serviceHostFactory

        foreach (Type serviceType in this.ServiceTypeProvider.Types)
        
            // I do some magic here to query base contracts because all our service implement a marker interface. But you don't need this. But then you might need to extend the type provider interface.
            IEnumerable<Type> contracts = QueryBaseContracts(serviceType );

            var host = this.CreateHost(serviceType);

            foreach (Type contract in contracts)
            
                Binding binding = this.CreateBinding();
                string address = this.CreateEndpointAddress(contract);

                this.AddServiceEndpoint(host, contract, binding, address);
            

            host.Description.Behaviors.Add(new ServiceFacadeBehavior());

            this.OpenHost(host);

            this.serviceHosts.Add(host);
        

    protected virtual ServiceHost CreateHost(Type serviceType )
    
        return this.serviceHostFactory(serviceType );
    

public class YourWcfModule : NinjectModule

    /// <summary>
    /// Loads the module into the kernel.
    /// </summary>
    public override void Load()
    

        this.Bind<Func<Type, ServiceHost>>().ToMethod(
            ctx =>
            (serviceType) =>
            ctx.Kernel.Get<NinjectServiceHost>(new ConstructorArgument("serviceType", serviceType), new ConstructorArgument("baseAddresses", new Uri[]  )));
    

玩得开心

【讨论】:

谢谢。但是在这种情况下,为什么我需要一个 NinjectServiceHost 呢?我不能将 IUserManager 绑定到 Singleton Scope 中的 UserManager,然后从 TimeService 的构造函数中的全局可用内核中获取它吗? 你可以。但这是著名的定位器模式方法。我总是建议尽可能多地进入组件不了解 DI 机制的方向。更清洁,更适合测试。 事实证明,当我使用这种“singletonInstance”方法时,我绑定了InstanceContextMode.Single 服务行为,这不是我需要的。如何仍然绑定到具有构造函数参数的类,但将类型传递给 NinjectServiceHost 构造函数? 海。编辑了上面显示每个请求解决方案的答案。如果需要,您可以询问更多详细信息

以上是关于使用 Ninject 2 将参数传递给 WCF ServiceHost 类型的主要内容,如果未能解决你的问题,请参考以下文章

无法将第二个参数传递给带有两个参数的 WCF 服务

无法以 GET 类型的方法将字典作为参数传递给 WCF REST 服务

将 json 参数传递给 WCF 函数给出错误“服务器在处理请求时遇到错误。有关更多详细信息,请参阅服务器日志”

Ninject 3、WCF服务和参数化构造函数

URL 未将参数传递给 s-s-rS 报告

是否可以使用 jQuery 方法 getJSON 跨域将复杂对象传递给 WCF 服务?