使用 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 类型的主要内容,如果未能解决你的问题,请参考以下文章
无法以 GET 类型的方法将字典作为参数传递给 WCF REST 服务