Instance per call

34 views
Skip to first unread message

Naresh Thandu

unread,
Mar 14, 2016, 12:00:10 PM3/14/16
to Autofac
Hello all,

Started using Autofac recently.

I have few levels of interfaces.

Interface IReader(){ void Invoke();}

Interface IMessageDispacthHandler(){}

Interface IMessageHandler(){}

Constructor of the 'Reader' takes the IMessageDispatchHandler and MessageDispatchHandler's constructor takes IEnumerable<IMessageHandler>

Invoke() method in Reader is expected to invoked in every 5 seconds and using a System.Timers.Timer.

I would like to have SingleInstance of Reader but new instances of IMessageHandler for every call on Invoke(different thread). Not sure how to achieve this with Autofac.

Any help would be appreciated.

Thanks,
Naresh

Alex Meyer-Gleaves

unread,
Mar 15, 2016, 8:34:57 AM3/15/16
to Autofac
Hi Naresh,

It looks like you need to inject an IEnumerable<Func<Owned<IMessageHandler>>> into the dispatcher. This will allow you to create new instances of the handler on demand using the Func. Those instances are wrapped in their own lifetime scope via the Owned instance and disposed of immediately after use.

If that all sounds a little weird and is totally new to you, then I would recommend reading Nick's great post introducing these concepts:


Here is a quick example of what I mean. I've added some methods to the interfaces to demonstrate the concepts.

void Main()
{
var builder = new ContainerBuilder();
builder.RegisterType<Reader>().As<IReader>().SingleInstance();
builder.RegisterType<Dispatcher>().As<IMessageDispatchHandler>().SingleInstance();
builder.RegisterType<Handler>().As<IMessageHandler>().InstancePerDependency();
var container = builder.Build();
var reader = container.Resolve<IReader>();
reader.Invoke();
reader.Invoke();
reader.Invoke();
}

interface IReader { void Invoke(); }

interface IMessageDispatchHandler { void Dispatch(); }

interface IMessageHandler { void Handle(); }

class Reader : IReader
{
IMessageDispatchHandler dispatcher;
public Reader(IMessageDispatchHandler dispatcher)
{
this.dispatcher = dispatcher;
}

public void Invoke()
{
dispatcher.Dispatch();
}
}

class Dispatcher : IMessageDispatchHandler
{
IEnumerable<Func<Owned<IMessageHandler>>> handlers;
public Dispatcher(IEnumerable<Func<Owned<IMessageHandler>>> handlers)
{
this.handlers = handlers;
}

public void Dispatch()
{
foreach (var handlerFactory in handlers)
using (var ownedHandler = handlerFactory())
ownedHandler.Value.Handle();
}
}

class Handler : IMessageHandler, IDisposable
{
public Handler()
{
Console.WriteLine($"Handler instance {GetHashCode()} created");
}
public void Handle()
{
Console.WriteLine($"Handler instance {GetHashCode()} invoked");
}

public void Dispose()
{
Console.WriteLine($"Handler instance {GetHashCode()} disposed");
}
}

The output from running the example is:

Handler instance 17800618 created
Handler instance 17800618 invoked
Handler instance 17800618 disposed
Handler instance 3908676 created
Handler instance 3908676 invoked
Handler instance 3908676 disposed
Handler instance 5833248 created
Handler instance 5833248 invoked
Handler instance 5833248 disposed

You can see new instances being created, invoked and disposed.

Hopefully this gets you further along the path and you enjoy using Autofac.

Cheers,

Alex.
Reply all
Reply to author
Forward
0 new messages