简体   繁体   English

使用Castle Windsor使用工厂方法解决WCF服务

[英]Using Castle windsor to resolve WCF service usingfactorymethod

I'm trying to see if this is possible. 我正在尝试看看是否有可能。 I want to resolve the WCF service class from castle windsor via a factory class. 我想通过工厂类来解决来自温莎城堡的WCF服务类。 The WCF service is hosted in IIS and so far I've only been getting a 404 when I try to call the service when using the factory. WCF服务托管在IIS中,到目前为止,当我尝试在使用工厂时调用该服务时,只得到404。 Here is my registration code: 这是我的注册码:

container.AddFacility<WcfFacility>();

container.Register(Component.For<IServiceFactory>() 
                            .ImplementedBy<ServiceFactory>()
                            .LifestyleSingleton());

container.Register(Component.For<IFooService>()
                            .UsingFactoryMethod((kernel, context)
                                    => kernel.Resolve<IServiceFactory>()
                                                     .CreateService(context.RequestedType))                                     
                            .Named("FooService")
                            .LifestylePerWcfOperation());

Here is my factory class: 这是我的工厂班级:

public class ServiceFactory : IServiceFactory
{
    public IFooService CreateService(Type forType)
    {
        IFooService createdType = null;

        if (forType == typeof(IFooService))
            createdType = new FooService();

        return createdType;
    }
}

I have tried doing a strait .ImplementedBy<FooService>() and that works fine. 我试图做一个海峡.ImplementedBy <FooService>(),并且工作正常。 It's only when I want to do it via a factory that I have a problem. 只有当我想通过工厂进行操作时,我才遇到问题。 Is this possible, meaning I'm missing something, or is it not possible? 这是否可能,这意味着我丢失了某些东西,还是不可能?

(I know that the code shown is pretty simple, I am only testing if its possible before fully implementing my factory code) (我知道显示的代码非常简单,我只是在完全实现我的工厂代码之前测试是否可行)

you don't have to create a custom ServiceHost to do this, though you're right this is harder than it should be. 不必创建一个自定义的ServiceHost要做到这一点,虽然你说的没错,这是难度比它应该是。 The article that eouw0o83hf references first talks about an IInstanceProvider. eouw0o83hf引用的文章首先讨论了一个IInstanceProvider。 That's the key, but you can wire it up using and WCF ServiceBehavior as well instead of a customer ServiceHost. 这是关键,但是您也可以使用WCF ServiceBehavior而不是客户ServiceHost进行连接。 I'm not sure what your FactoryMethod has to do with this - it sounds like it's a general wire up issue... or I'm not understanding your problem. 我不确定您的FactoryMethod与此有何关系-听起来像是一般的接线问题...或者我不了解您的问题。 I'll show below how I do the wire up without the ServiceHost and hopefully that fixes your problem. 我将在下面显示在没有ServiceHost的情况下如何进行连接,希望可以解决您的问题。

First create a class that implements IInstanceProvider - mine below calls out to my ObjectResolver class with wraps Windsor. 首先创建一个实现IInstanceProvider的类-下面的我用包装的Windsor调用了我的ObjectResolver类。 I'll leave that out for brevity. 为了简洁起见,我将其省略。

using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Dispatcher;

public class ObjectResolverInstanceProvider : IInstanceProvider
{
    private readonly Type _serviceType;

    public ObjectResolverInstanceProvider(Type serviceType)
    {
        _serviceType = serviceType;
    }

    public object GetInstance(InstanceContext instanceContext)
    {
        return ObjectResolver.Resolve(_serviceType);
    }

    public object GetInstance(InstanceContext instanceContext, Message message)
    {
        return ObjectResolver.Resolve(_serviceType);
    }

    public void ReleaseInstance(InstanceContext instanceContext, object instance)
    {
        ObjectResolver.Release(instance);
    }
}

Then create a service behavior that assigns your instance provider to each endpoint's DispatchRuntime's InstanceProvider: 然后创建一个服务行为,将您的实例提供程序分配给每个终结点的DispatchRuntime的InstanceProvider:

using System;
using System.Collections.ObjectModel;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;

public class ConstructWithObjectResolverAttribute : Attribute, IServiceBehavior
{
    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
    {
        foreach (ChannelDispatcherBase cdb in serviceHostBase.ChannelDispatchers)
        {
            ChannelDispatcher cd = cdb as ChannelDispatcher;

            if (cd != null)
            {
                foreach (EndpointDispatcher ed in cd.Endpoints)
                {
                    ed.DispatchRuntime.InstanceProvider = new ObjectResolverInstanceProvider(serviceDescription.ServiceType);
                }
            }
        }
    }

    public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
    {
    }

    public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
    {
    }
}

Next apply the service attribute to your service implementation... note you could do this in config if you wanted too, but I prefer applying it via an attribute like so: 接下来将service属性应用于您的服务实现...请注意,如果您也可以在config中执行此操作,但我更喜欢通过如下属性来应用它:

   [ConstructWithObjectResolver]
   [ServiceBehavior(Namespace="YourNamespace")]
   public class FooService : IFooService {}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM