kurabdurbos
kurabdurbos

Reputation: 277

How do you consume WCF services from a console app using Autofac?

So I have a console application in which I am using Autofac.

I have set up my console application as follows:

I have a class I call ContainerConfig - In this I have all my builder registrations:

public static class ContainerConfig
{
    public static IContainer Configure()
    {
        var builder = new ContainerBuilder();

        builder.Register(c => new MatchRun()).As<MatchRun>).SingleInstance();


        builder.RegisterType<AuditLogic>().As<IAuditLogic>();
        builder.RegisterType<AuditRepository>().As<IAuditRepository>();

        builder.RegisterType<ValidationLogic>().As<IValidationLogic>();

        return builder.Build();
    }
}

I call my main applcation as follows:

    private static void Main(string[] args)
    {
        var container = ContainerConfig.Configure();
        using (var scope = container.BeginLifetimeScope())
        {
            var app = scope.Resolve<IApplication>();

            app.Run(args);

        }
    }

The issue is that I have a connected WCF service. This is my AuditRepository. (FYI - I have not touched WCF for years so I have forgotten most of what I knew).

Its currently constructed to create and dispose of the the proxy each time I make a call to that client. This functions - mostly.

Looks like this:

    public string GetStuff(string itemA, string itemB)
    {
        try
        {
            GetProxy();
            return _expNsProxy.GetStuff(itemA, itemb);
        }
        catch (Exception ex)
        {
            IMLogger.Error(ex, ex.Message);
            throw ex;
        }
        finally
        {
           // CloseProxyConn();
        }
    }

What i am wondering is can I do this better with Autofac - creating a single instance vs the constant open close - or am I just totally crazy? I know I am not fully asking this the right way - not 100% sure how to actually word the question.

Thanks

Upvotes: 0

Views: 202

Answers (1)

Aleš Doganoc
Aleš Doganoc

Reputation: 12052

The approach to always create a new proxy and close it after each call is good for WCF.

Otherwise you can run into issues. For example if one service call fails the channel created by the proxy goes into a faulted state and you can not do more calls on it just abort it. Then you need to create a new proxy. Also you can have threading issues if you call the same proxy from multiple threads simultaneously.

Check also this documentation with a sample of how to handle errors correctly when calling WCF services.

There is an Autofac.Wcf package that can help you with the creation and freeing of channels. Check the documentation here. It uses the dynamic client generation approach where you just give the interface of your WCF service and it generates the channel based on the interface. This is a bit more low level approach so you will have to understand more what is going on. The generated client class does this for you in the background.

You need two registrations one for the channel factory that is a singleton:

builder
  .Register(c => new ChannelFactory<IYourWcfService>(
    new BasicHttpBinding(), // here you will have to configure the binding correctly
    new EndpointAddress("http://localhost/YourWcfService.svc")))
  .SingleInstance();

And a factory registration that will create the channel from the factory every time you request the service:

builder
  .Register(c => c.Resolve<ChannelFactory<IYourWcfService>>().CreateChannel())
  .As<IIYourWcfService>()
  .UseWcfSafeRelease();

Upvotes: 1

Related Questions