get { return description; }
}
- protected IDictionary<string,ContractDescription> ImplementedContracts {
+ protected internal IDictionary<string,ContractDescription> ImplementedContracts {
get { return contracts; }
}
return AddServiceEndpointCore (cd, binding, ea, listenUri);
}
-#if NET_4_0
public virtual void AddServiceEndpoint (ServiceEndpoint endpoint)
{
if (endpoint == null)
Description.Endpoints.Add (endpoint);
}
-#endif
Type PopulateType (string typeName)
{
ServiceElement service = GetServiceElement ();
if (service != null)
- ApplyServiceElement (service);
-
+ LoadConfigurationSection (service);
+ // simplified configuration
+ AddServiceBehaviors (String.Empty, false);
// TODO: consider commonBehaviors here
// ensure ServiceAuthorizationBehavior
Description.Behaviors.Add (debugBehavior);
}
}
+
+ void AddServiceBehaviors (string configurationName, bool throwIfNotFound)
+ {
+ if (configurationName == null)
+ return;
+ ServiceBehaviorElement behavior = ConfigUtil.BehaviorsSection.ServiceBehaviors [configurationName];
+ if (behavior == null) {
+ if (throwIfNotFound)
+ throw new ArgumentException (String.Format ("Service behavior configuration '{0}' was not found", configurationName));
+ return;
+ }
+
+ KeyedByTypeCollection<IServiceBehavior> behaviors = Description.Behaviors;
+ foreach (var bxe in behavior) {
+ IServiceBehavior b = (IServiceBehavior) bxe.CreateBehavior ();
+ if (behaviors.Contains (b.GetType ()))
+ continue;
+ behaviors.Add (b);
+ }
+ }
void ApplyServiceElement (ServiceElement service)
{
}
// behaviors
- ServiceBehaviorElement behavior = ConfigUtil.BehaviorsSection.ServiceBehaviors [service.BehaviorConfiguration];
- if (behavior != null) {
- foreach (var bxe in behavior) {
- IServiceBehavior b = (IServiceBehavior) bxe.CreateBehavior ();
- Description.Behaviors.Add (b);
- }
- }
- else if (!String.IsNullOrEmpty (service.BehaviorConfiguration))
- throw new ArgumentException (String.Format ("Service behavior configuration '{0}' was not found", service.BehaviorConfiguration));
+ AddServiceBehaviors (service.BehaviorConfiguration, true);
- // services
+ // endpoints
foreach (ServiceEndpointElement endpoint in service.Endpoints) {
ServiceEndpoint se;
-#if NET_4_0
var binding = String.IsNullOrEmpty (endpoint.Binding) ? null : ConfigUtil.CreateBinding (endpoint.Binding, endpoint.BindingConfiguration);
- if (endpoint.Kind != null) {
+ if (!String.IsNullOrEmpty (endpoint.Kind)) {
var contract = String.IsNullOrEmpty (endpoint.Contract) ? null : GetContract (endpoint.Contract, false);
se = ConfigUtil.ConfigureStandardEndpoint (contract, endpoint);
if (se.Binding == null)
se.Binding = binding;
- if (se.Address == null && se.Binding != null)
+ if (se.Address == null && se.Binding != null) // standard endpoint might have empty address
se.Address = new EndpointAddress (CreateUri (se.Binding.Scheme, endpoint.Address));
+ if (se.Binding == null && se.Address != null) // look for protocol mapping
+ se.Binding = ConfigUtil.GetBindingByProtocolMapping (se.Address.Uri);
AddServiceEndpoint (se);
}
- else
+ else {
+ if (binding == null && endpoint.Address != null) // look for protocol mapping
+ binding = ConfigUtil.GetBindingByProtocolMapping (endpoint.Address);
se = AddServiceEndpoint (endpoint.Contract, binding, endpoint.Address);
-#else
- var binding = ConfigUtil.CreateBinding (endpoint.Binding, endpoint.BindingConfiguration);
- se = AddServiceEndpoint (endpoint.Contract, binding, endpoint.Address);
-#endif
+ }
// endpoint behaviors
EndpointBehaviorElement epbehavior = ConfigUtil.BehaviorsSection.EndpointBehaviors [endpoint.BehaviorConfiguration];
foreach (ServiceEndpoint endPoint in Description.Endpoints)
endPoint.Validate ();
+ // In 4.0, it seems that if there is no configured ServiceEndpoint, infer them from the service type.
+ if (Description.Endpoints.Count == 0) {
+ foreach (Type iface in Description.ServiceType.GetInterfaces ())
+ if (iface.GetCustomAttributes (typeof (ServiceContractAttribute), true).Length > 0)
+ foreach (var baddr in BaseAddresses) {
+ if (!baddr.IsAbsoluteUri)
+ continue;
+ var binding = ConfigUtil.GetBindingByProtocolMapping (baddr);
+ if (binding == null)
+ continue;
+ AddServiceEndpoint (iface.FullName, binding, baddr);
+ }
+ }
+
if (Description.Endpoints.FirstOrDefault (e => e.Contract != mex_contract && !e.IsSystemEndpoint) == null)
throw new InvalidOperationException ("The ServiceHost must have at least one application endpoint (that does not include metadata exchange endpoint) defined by either configuration, behaviors or call to AddServiceEndpoint methods.");
}
- [MonoTODO]
- protected void LoadConfigurationSection (ServiceElement element)
+ protected void LoadConfigurationSection (ServiceElement serviceSection)
{
- ServicesSection services = ConfigUtil.ServicesSection;
+ ApplyServiceElement (serviceSection);
}
- [MonoTODO]
protected override sealed void OnAbort ()
{
+ OnCloseOrAbort (TimeSpan.Zero);
}
Action<TimeSpan> close_delegate;
}
protected override void OnClose (TimeSpan timeout)
+ {
+ OnCloseOrAbort (timeout);
+ }
+
+ void OnCloseOrAbort (TimeSpan timeout)
{
DateTime start = DateTime.Now;
ReleasePerformanceCounters ();
foreach (IEndpointBehavior b in endPoint.Behaviors)
b.ApplyDispatchBehavior (endPoint, ed);
foreach (OperationDescription operation in endPoint.Contract.Operations) {
+ if (operation.InCallbackContract)
+ continue; // irrelevant
foreach (IOperationBehavior b in operation.Behaviors)
b.ApplyDispatchBehavior (operation, ed.DispatchRuntime.Operations [operation.Name]);
}