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

Max*_*lov 3 c# wcf ninject

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

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

public MyWCFHandler(UserManager manager)
{
  _manager = manager;
}
Run Code Online (Sandbox Code Playgroud)

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

我不想搞乱如何在我的wcf服务上将值传递给构造函数中提供的自定义ServiceHost ?

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

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

  1. 在我的项目中引用Ninject和Ninject.Extensions.WCF.
  2. 创建一个继承Ninject模块的类,并编写如下内容:

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

  3. 将使用新ServiceModule()初始化的内核添加到KernelContainer.

  4. 像这样使用NinjectServiceHost:

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

在那里我应该准备好我的主人打开.

问题是:

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

遗憾的是,没有一个示例可以简单地显示参数化的ServiceHost启动.我甚至不关心它是否是我使用的Ninject.无论哪种解决方案都有一个很好的例子 - 我很好,因为我只是决定使用什么IoC容器.

Dan*_*ach 6

关于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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

按请求方式:

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[] { })));
    }
}
Run Code Online (Sandbox Code Playgroud)

玩得开心