2013-08-29 47 views
1

我正在使用Windows服务与城堡windsor wcffacility使用TCP绑定托管双工wcf服务。Castle Windsor - 解决双工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地址属性为null。 ChannelFactory的端点必须具有指定的有效地址。

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

-

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

回答

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