我正在使用带有城堡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" />
答案 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));