使用Castle windsor使用factory方法解析WCF服务

时间:2013-08-02 17:50:51

标签: c# wcf castle-windsor factory-pattern

我正试图看看这是否可行。我想通过工厂类从city windsor解析WCF服务类。 WCF服务托管在IIS中,到目前为止,当我在使用工厂时尝试调用服务时,我只获得了404。这是我的注册码:

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

这是我的工厂类:

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

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

        return createdType;
    }
}

我试过做一个海峡.ImplementedBy&lt; FooService&gt;()并且工作正常。只有当我想通过工厂做这件事我才有问题。这是可能的,这意味着我错过了一些东西,还是不可能?

(我知道显示的代码非常简单,我只是在完全实现我的工厂代码之前测试它是否可行)

1 个答案:

答案 0 :(得分:0)

你没有拥有来创建一个自定义的ServiceHost来做到这一点,尽管你是对的,这比它应该更难。 eouw0o83hf首先引用的文章讨论了一个IInstanceProvider。这是关键,但你可以使用和WCF ServiceBehavior而不是客户ServiceHost连接它。我不确定你的FactoryMethod与此有什么关系 - 听起来这是一个普通的接线问题......或者我不理解你的问题。我将在下面展示如何在没有ServiceHost的情况下进行连接,并希望能解决您的问题。

首先创建一个实现IInstanceProvider的类 - 我的下面使用包装Windsor调用我的ObjectResolver类。为了简洁,我会把它留下来。

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

然后创建一个服务行为,将您的实例提供程序分配给每个端点的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)
    {
    }
}

接下来将service属性应用于您的服务实现...请注意,如果您也愿意,可以在config中执行此操作,但我更喜欢通过如下属性应用它:

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