1

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

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

当我在解决时在客户端使用城堡温莎时出现问题。下面是用于通过基于配置文件的代码添加 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());

    }

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

 [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 属性为空。ChannelFactory 的端点必须指定一个有效的地址。

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

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

1 回答 1

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));
于 2013-08-29T16:38:35.430 回答