首页 文章

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

提问于
浏览
3

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

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

public MyWCFHandler(UserManager manager)
{
  _manager = manager;
}

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

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

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

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

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

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

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

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

  • 像这样使用NinjectServiceHost:

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

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

问题是:

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

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

1 回答

  • 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();
            }
        }
    }
    

    按请求方式:

    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[] { })));
        }
    }
    

    玩得开心

相关问题