1 // Copyright 2004-2008 Castle Project - http://www.castleproject.org/
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
7 // http://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
15 namespace Castle
.Facilities
.WcfIntegration
18 using System
.Collections
.Generic
;
19 using System
.Threading
;
21 using Castle
.MicroKernel
;
22 using Castle
.Facilities
.WcfIntegration
.Internal
;
24 public class WcfClientResolver
: ISubDependencyResolver
26 private readonly ICollection
<WcfClientModel
> clientModels
;
27 private readonly Dictionary
<Type
, CreateChannel
> channelCreators
;
28 private readonly ReaderWriterLock locker
;
30 public WcfClientResolver(WcfClientModel
[] clientModels
)
32 this.clientModels
= clientModels
;
33 channelCreators
= new Dictionary
<Type
, CreateChannel
>();
34 locker
= new ReaderWriterLock();
37 public bool CanResolve(CreationContext context
, ISubDependencyResolver parentResolver
,
38 ComponentModel model
, DependencyModel dependency
)
40 return ResolveClientModel(dependency
.TargetType
, model
, context
) != null;
43 public object Resolve(CreationContext context
, ISubDependencyResolver parentResolver
,
44 ComponentModel model
, DependencyModel dependency
)
46 WcfClientModel clientModel
=
47 ResolveClientModel(dependency
.TargetType
, model
, context
);
49 if (clientModel
!= null)
51 return GetChannelBuilder(clientModel
)();
54 throw new InvalidOperationException(string.Format(
55 "Could not find a client supporting contract {0}", dependency
.TargetType
));
58 private WcfClientModel
ResolveClientModel(Type contract
, ComponentModel model
, CreationContext context
)
60 WcfClientModel clientModel
;
61 Predicate
<WcfClientModel
> contractMatch
= delegate(WcfClientModel candidate
)
63 return contract
== candidate
.Contract
;
66 // First, try the contexrt overrides.
67 if (context
!= null && context
.HasAdditionalParameters
)
69 if (WcfUtils
.FindDependency
<WcfClientModel
>(
70 context
.AdditionalParameters
, contractMatch
,
77 // Then try the component overrides.
80 if (WcfUtils
.FindDependency
<WcfClientModel
>(
81 model
.CustomDependencies
, contractMatch
,
88 // Finally, try the client models.
89 if (WcfUtils
.FindDependency
<WcfClientModel
>(
90 clientModels
, contractMatch
, out clientModel
))
98 private CreateChannel
GetChannelBuilder(WcfClientModel clientModel
)
100 CreateChannel channelCreator
;
102 locker
.AcquireReaderLock(Timeout
.Infinite
);
106 if (channelCreators
.TryGetValue(clientModel
.Contract
, out channelCreator
))
108 return channelCreator
;
111 locker
.UpgradeToWriterLock(Timeout
.Infinite
);
113 if (channelCreators
.TryGetValue(clientModel
.Contract
, out channelCreator
))
115 return channelCreator
;
118 channelCreator
= new ChannelBuilder().GetChannelCreator(clientModel
.Endpoint
);
119 channelCreators
[clientModel
.Contract
] = channelCreator
;
120 return channelCreator
;
124 locker
.ReleaseLock();