WCF с Unity, настройка зависимостей через код - PullRequest
2 голосов
/ 19 марта 2011

Я использую решение, предоставленное Drew (с источником) для внедрения единства в службы WCF. Решение внутренне добавляет точки расширения в WCF через поставщика экземпляров и поведения. Я могу заставить его работать с моим текущим проектом. Но проблема, с которой я сталкиваюсь при таком подходе, заключается в том, что контейнер Unity инициализируется динамически, читая XML-файл в файле конфигурации в проекте расширения.

Я использую единство с автоматическими фабриками, и он не поддерживается для настройки через xml, и я ищу способ использовать код для регистрации зависимостей вместо xml из проекта службы. Как мне достать единицу контейнера

Любые идеи.

1 Ответ

2 голосов
/ 19 марта 2011

Мне нравится отвечать на мои собственные вопросы.

В текущем решении UnityInstanceProvider был жестко запрограммирован, и все, что мне нужно, это расширить инициализацию, чтобы я мог переопределить.

public class UnityBehaviorExtensionElement : BehaviorExtensionElement
{
    protected override object CreateBehavior()
    {
        return new UnityServiceBehavior()
        {
            InstanceProviderFunc = InstanceProviderFunc(),
            ContainerName = this.ContainerName,
            ContextChannelEnabled = this.ContextChannelEnabled,
            InstanceContextEnabled = this.InstanceContextEnabled,
            OperationContextEnabled = this.OperationContextEnabled,
            ServiceHostBaseEnabled = this.ServiceHostBaseEnabled
        };
    }

    protected virtual Func<Type, string, UnityInstanceProvider> InstanceProviderFunc()
    {
        return (type, str) => new UnityInstanceProvider(type, str, UnityInstanceProvider.CreateUnityContainer);
    }
}
    UnityServiceBehavior: IServiceBehavior
    {
    ....
    public Func<Type, string, UnityInstanceProvider> InstanceProviderFunc;


    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)

    ...

                foreach (ChannelDispatcherBase channelDispatcherBase in serviceHostBase.ChannelDispatchers)
                {
                    ChannelDispatcher channelDispatcher = channelDispatcherBase as ChannelDispatcher;
                    if (channelDispatcher != null)
                    {
                        foreach (EndpointDispatcher endpointDispatcher in channelDispatcher.Endpoints)
                        {
                            endpointDispatcher.DispatchRuntime.InstanceProvider =
                                InstanceProviderFunc(serviceDescription.ServiceType, this.ContainerName);
    ....
    }

Итеперь я могу определить свой собственный BehaviorExtensionElement внутри моего сервисного проекта и переопределить InstanceProviderFunc

public class TestClientBehaviorExtensionElement:UnityBehaviorExtensionElement
{
    protected override Func<Type, string, UnityInstanceProvider> InstanceProviderFunc()
    {
        return (type, str) => new UnityInstanceProvider(type, str, CreateUnityContainer);
    }

    ///<summary>
    ///</summary>
    ///<param name="containerName"></param>
    ///<returns></returns>
    public IUnityContainer CreateUnityContainer(string containerName)
    {
        IUnityContainer unityContainer = new UnityContainer();
        try
        {
            unityContainer.RegisterType<IOperationContextService, OperationContextService>(new UnityOperationContextLifetimeManager());
          ...
        }
        catch (Exception)
        {
            unityContainer.Dispose();
            throw;
        }

        return unityContainer;
    }
...