WCF + Unity вложенная проблема web.config - PullRequest
1 голос
/ 14 декабря 2010

Я пытаюсь настроить следующее:

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

Я поместил свою конфигурацию WCF Service + в папку / WebApplication / Services.

Это все еще работает, как и ожидалось.

Теперь мой AccessTokenService, который находится в другой сборке, ожидает интерфейс в своем конструкторе с именем IAccessTokenRepository (см. Все примеры кода ниже).

Поскольку обычно WCF допускает только конструкторы без параметров,Я расширил WCF с помощью пользовательского IInstanceProvider, IServiceBehavior и BehaviorExtensionElement, чтобы Unity могла разрешить это для меня.

Как и в случае с настройкой WCF, я также поместил конфигурацию Unity в файл web.config, который находится в Сервисахпапка.Таким образом, я не загрязняю свой web.config в корне моего веб-приложения.Но это не похоже на работу.Я не могу прочитать раздел конфигурации Unity из файла web.config в папке служб. Часть GetSection следующего кода возвращает нуль:

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");
    }
}

Теперь, если я перенесу конфигурацию 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)
    {

    }        
}
...