skjagini
skjagini

Reputation: 3217

WCF with Unity, configuring the dependencies through code

I am using the solution provided by the Drew (with Source) to inject unity into WCF services. The solution internally adds extension points to WCF through instance provider and behaviors. I am able to get it to work with my current project. But the problem I am facing with this approach is the unity container is initialized dynamically by reading the xml in config file in the extension project.

I am using unity with auto factories and it is not supported to configure through xml, and looking for a way to use code to register dependencies instead of xml from the service project. How do I get hold of unity container

Any ideas.

Upvotes: 2

Views: 1027

Answers (1)

skjagini
skjagini

Reputation: 3217

I like to answer my own questions.

In the current solution, UnityInstanceProvider was hard coded and all I have to was extend the initialization so I can override.

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

And now I can define my own BehaviorExtensionElement inside my service project and override the 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;
    }

Upvotes: 2

Related Questions