开发者

WCF + Unity nested web.config problem

I'm trying to setup the following:

/WebApplication
    web.config
    tokenlogin.aspx
    /Services
        web.config
        AccessTokenService.svc

I put my WCF Service + configuration in the /WebApplication/Services folder.

This still workes as expected.

Now my AccessTokenService, which resides in an other assembly, expects an interface in its constructor called IAccessTokenRepository (see all code samples below).

Because normally WCF only allows for parameter-less constructors, I extended WCF using a custom IInstanceProvider, IServiceBehavior and BehaviorExtensionElement so Unity could resolve this for me.

As I did with the WCF configuration, I also put the Unity configuration inside the web.config file which resides in the Services folder. This way I don't pollute my web.config in my web app root. But that doesn't seem to work. I'm unable to read the unity configuration section from the web.config in the services folder. The GetSection part of the follwing code returns 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");
    }
}

Now if I move the unity configuration to the web.config int the root of the WebApplication everything works fine. And I have no idea why.

The rest of the code:

[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 acc开发者_StackOverflow社区essTokenRequest)
    {
        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)
    {

    }        
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜