我正在尝试设置以下内容:
/WebApplication web.config tokenlogin.aspx /Services web.config AccessTokenService.svc
我将我的WCF服务+配置放在/ WebApplication / Services文件夹中。
这仍然按预期工作。
现在我的AccessTokenService驻留在另一个程序集中,它的构造函数中需要一个名为IAccessTokenRepository的接口(参见下面的所有代码示例)。
因为通常WCF只允许无参数构造函数,所以我使用自定义IInstanceProvider,IServiceBehavior和BehaviorExtensionElement扩展了WCF,因此Unity可以为我解决这个问题。
正如我对WCF配置所做的那样,我还将Unity配置放在了驻留在Services文件夹中的web.config文件中。这样我就不会在我的web应用程序根目录中污染我的web.config。但这似乎不起作用。我无法从services文件夹中的web.config读取unity配置部分。 以下代码的GetSection部分返回null:
public class UnityBehaviorExtensionElement : BehaviorExtensionElement
{
public override Type BehaviorType
{
get { return typeof(UnityServiceBehaviour); }
}
protected override object CreateBehavior()
{
UnityContainer unityContainer = new UnityContainer();
UnityConfigurationSection section = LoadUnitySection() as UnityConfigurationSection;
section.Containers.Default.Configure(unityContainer);
return new UnityServiceBehaviour(unityContainer);
}
private object LoadUnitySection()
{
if (System.Web.Hosting.HostingEnvironment.IsHosted)
return WebConfigurationManager.GetSection("unity");
return ConfigurationManager.GetSection("unity");
}
}
现在,如果我将统一配置移动到web.config的根目录,那么WebApplication的根目录一切正常。我不明白为什么。
其余代码:
[ServiceContract(Namespace = "http://services.xxx.com/AccessTokenService/1.0")]
public interface IAccessTokenService
{
[OperationContract]
Guid RequestAccessToken(AccessTokenRequest accessTokenRequest);
}
public class AccessTokenService : IAccessTokenService
{
private readonly IAccessTokenRepository accessTokenRepository;
public AccessTokenService(IAccessTokenRepository accessTokenRepository)
{
if (accessTokenRepository == null)
throw new ArgumentNullException("accessTokenRepository");
this.accessTokenRepository = accessTokenRepository;
}
public Guid RequestAccessToken(AccessTokenRequest accessTokenRequest)
{
return accessTokenRepository.Store(accessTokenRequest);
}
}
public class UnityInstanceProvider : IInstanceProvider
{
private readonly Type serviceType;
private readonly UnityContainer unityContainer;
public UnityInstanceProvider(Type serviceType, UnityContainer unityContainer)
{
this.serviceType = serviceType;
this.unityContainer = unityContainer;
}
#region IInstanceProvider Members
public object GetInstance(InstanceContext instanceContext, System.ServiceModel.Channels.Message message)
{
return unityContainer.Resolve(serviceType);
}
public object GetInstance(InstanceContext instanceContext)
{
return GetInstance(instanceContext, null);
}
public void ReleaseInstance(InstanceContext instanceContext, object instance)
{
if (instance == null)
return;
if (instance is IDisposable)
((IDisposable)instance).Dispose();
}
#endregion
}
public class UnityServiceBehaviour : IServiceBehavior
{
private readonly UnityContainer unityContainer;
public UnityServiceBehaviour(UnityContainer unityContainer)
{
this.unityContainer = unityContainer;
}
public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection endpoints, BindingParameterCollection bindingParameters)
{
}
public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
foreach (var channel in serviceHostBase.ChannelDispatchers.OfType())
{
if (channel == null)
continue;
foreach (var endPointDispatcher in channel.Endpoints)
{
endPointDispatcher.DispatchRuntime.InstanceProvider =
new UnityInstanceProvider(serviceDescription.ServiceType, unityContainer);
}
}
}
public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
}
}