Castle Windsor - 解决双工wcf服务

时间:2013-08-29 08:25:20

标签: wcf c#-4.0 castle-windsor

我正在使用带有城堡windsor wcffacility的Windows服务使用TCP绑定来托管双工wcf服务。

我认为,当我向控制台应用程序添加服务引用时,托管没有问题。我可以毫无问题地访问双工服务。

当我在解析时在客户端使用城堡windsor时出现问题。下面是用于通过基于配置文件的代码添加wcf服务的代码。

public static IWindsorContainer RegisterWcfClients(IocBuildSettings iocBuildSettings,
        IWindsorContainer container)
    {

        //Register callback methods for duplex service first.

        container.Register(Component.For<INotificationCallback>()
            .ImplementedBy<NotificationCallbackCastle>()
            .LifestyleTransient());



        // get dictionary with key = service class, value = service interface
        var servicesWithWcfInterfaces = Assembly.GetAssembly(typeof (IApplicationService))
            .GetTypes()
            .Where(x => (x.IsInterface || x.IsClass) && HasServiceContract(x))
            .ToList();
        var registrations = new List<IRegistration>();

        //get the client section in System.ServiceModel from web.config file
        var clientSection = ConfigurationManager.GetSection("system.serviceModel/client") as ClientSection;
        //get the endpointsCollection from childSection
        var endpointCollection =
            clientSection.ElementInformation.Properties[string.Empty].Value as ChannelEndpointElementCollection;



        foreach (var serviceInterface in servicesWithWcfInterfaces)
        {
            //get the childEndpoint name from web.config file
            var endpointName = GetClientEndpointName(endpointCollection, serviceInterface);

            //register services which are declared in web.config file only.
            if (string.IsNullOrEmpty(endpointName)) continue;

            // attribute is either on the service class or the interface
            var attribute =
                (ServiceContractAttribute)
                    (Attribute.GetCustomAttribute(serviceInterface, typeof (ServiceContractAttribute)));
            if (attribute != null)
            {
                WcfClientModelBase model = null;
                // handle duplex differently
                if (attribute.CallbackContract != null)
                {
                    model = new DuplexClientModel
                    {
                        Endpoint =
                            WcfEndpoint.ForContract(serviceInterface).FromConfiguration(endpointName)
                    }.Callback(container.Resolve(attribute.CallbackContract));
                    registrations.Add(WcfClient.ForChannels(model).Configure(c => c.LifestyleSingleton()));
                }
                else
                {
                    //regular attributes
                    model = new DefaultClientModel
                    {
                        Endpoint = WcfEndpoint.ForContract(serviceInterface).FromConfiguration(endpointName)
                    };
                    registrations.Add(WcfClient.ForChannels(model).Configure(c => c.LifestyleTransient()));
                }
            }
        } 
        return container.Register(registrations.ToArray());

    }

我只托管一项双工服务,以下是servicecontracts -

 [ServiceContract(CallbackContract = typeof(INotificationCallback))]
public interface INotificationService
{
    [OperationContract(IsOneWay = false)]
    void Subscribe(Guid subscriptionId, string userName, string[] eventNames);
    [OperationContract(IsOneWay = true)]
    void EndSubscribe(Guid subscriptionId);
}

[ServiceContract]
public interface INotificationCallback
{
    [OperationContract(IsOneWay = true)]
    void ReceiveNotification(NotificationResultDto notificationResult);
}

[DataContract]
public class NotificationResultDto
{
    [DataMember]
    public string UserName { get; set; }
    [DataMember]
    public string NotificationMessage { get; set; }
}

当我尝试使用以下语句解析双工服务时。 var temp = _container.Resolve();

我收到错误 -

WcfClientActivator:无法代理组件c2a216c2-af61-4cb2-83ba-e4d9a5cc4e68 内部异常 - ChannelFactory.Endpoint上的Address属性为null。 ChannelFactory的端点必须具有指定的有效地址。

在客户端部分下的web.config文件中 -

<endpoint address="net.tcp://localhost:9877/NotificationService" binding="netTcpBinding"
    bindingConfiguration="netTcpBindingConfiguration" contract="ServiceContracts.INotificationService"
    name="INotificationService_Endpoint" />

1 个答案:

答案 0 :(得分:1)

经过几个小时的挣扎,我找到了解决这个问题的方法。  我认为这可能是Castle Windsor中的一个错误,在创建DuplexClientModel时,无法使用“FromConfiguration”创建端点。它在运行时解析时失败。但是“DefaultClientModel”可以正常工作。

我的解决方法是阅读配置文件并获取地址,绑定和合同细节,并使用它们在代码中创建端点。

model = new DuplexClientModel
                    {
                        //Endpoint = WcfEndpoint.ForContract(serviceInterface).FromConfiguration(endpointName)
                        //FromConfiguration method is failing for some reason,could be b.u.g in castle, 
                        //so had to do this workaround by reading the web.config file and creating the Endpoint 
                        //from there manually.
                        Endpoint = WcfEndpoint.ForContract(serviceInterface)
                                    .BoundTo(CreateBindings(clientEndpoint.Binding))
                                    .At(clientEndpoint.Address)

                    }.Callback(container.Resolve(attribute.CallbackContract));