Multi Thread Question

28 views
Skip to first unread message

glen...@gmail.com

unread,
Aug 27, 2014, 2:26:45 PM8/27/14
to aut...@googlegroups.com
Hi All,

I am new to Autofac and DI in general but I find it very powerful and look forward to integrating Autofac into some existing applications.

I have a WCF endpoint which handles multiple requests concurrently and I have used the Autofac.Wcf to inject a LogManager into the constructor of my handling class which works great. Also injected into that constructor is an IIndex of interfaces that can potentially handle that request depending on some information in the body of the request.

When the handling (c lass that implements the service contract interface) code is constructed I create a logger from the injected LogManager. This logger has data specific to this request, correlationId, etc. In the action operation code I use the injected IIndex to get the correct processor which works fine.

The problem is I need to inject the logger that was created in the handler constructor so I have all the ident info for that request. Since I don't register loggers into autofac, only the logmanager is registered, I don't see an elegant way to use autofac to automatically inject my logger instance. I know I can manually set the logger from the instance created from the IIndex but I was looking for some DI way to handle this.

I could also register my logger instance with my logmanager and have autofac inject the log manager into the processor but that seems like it is overly complex.

Any other ideas or anything would be great!

Thanks

Glenn

Kendall Bennett

unread,
Aug 28, 2014, 9:35:40 AM8/28/14
to <autofac@googlegroups.com>
Unless you specifically request it WCF services are not threaded. A new instance of the WCF service class is created to handle each request as if comes in, which means you don't have to worry about threading issues. The only way you would end up with threading issues for a WCF service class is if you specifically decorate it to run in single instance mode, which is really not recommended.

Are you running in single instance mode? What more are you running it under? Here is more info:


The default is per session which is basically per call if you are not also using WCF session support.

Regards,

Sent from my iPad Air!

--
You received this message because you are subscribed to the Google Groups "Autofac" group.
To unsubscribe from this group and stop receiving emails from it, send an email to autofac+u...@googlegroups.com.
To post to this group, send email to aut...@googlegroups.com.
Visit this group at http://groups.google.com/group/autofac.
For more options, visit https://groups.google.com/d/optout.

Kaleb Pederson

unread,
Aug 28, 2014, 11:05:38 AM8/28/14
to aut...@googlegroups.com
If you haven't already looked at it, you'll at least want to look at the logger injection documentation: https://code.google.com/p/autofac/wiki/Log4NetIntegration.

I don't quite follow the problem. It sounds like you simply inject a LogManager and then you build the logger with "data specific to this request." What I don't understand is why you "need to inject the logger that was created in the handler constructor so I have all the ident info for that request?"

I'm reading that as you have all the necessary information, create a logger with the necessary context, and then want that to inject that into the instances returned by the IIndex, is that correct?

If that's correct, you have at least one pretty easy option:

If instead of requesting IIndex<THandler> you request IIndex<Func<ILogger, THandler>> you'll get back a function that takes in a logger and provides the handler. Assuming the handler is registered appropriately (isn't single instance, for example), this gives you the opportunity to provide the logger that should be injected into the handler. Note that when you do use Func<TParam, TResolved> the provided TParam is only overridden for TResolved. So if TResolved has a dependency TDep1 that depends on TParam, the TParam that you provide isn't going to be the same one injected into TDep1.

Often times the above is roughly equivalent to creating a factory that can provide the logger. Like the Log4NetIntegration above, you'd probably use AttachToComponentRegistration to retrieve necessary information about the registered object.

You may also be able to make the logger a method parameter rather than require it as a constructor dependency so that you can provide the correct dependency. This may or may not make sense within your architecture.

HTH,

--Kaleb



glen...@gmail.com

unread,
Sep 2, 2014, 3:13:47 PM9/2/14
to aut...@googlegroups.com, glen...@gmail.com
Hi Kaleb,

That is great information and it worked perfectly, thanks for the detailed post.

If you happen to read this can you give a quick overview of why using IIndex is better to use than ResolveKeyed? The reason I ask is I use the ResolveKeyed I can add registrations in a scope which does not seem to work if I use the IIndex.

Example:

using (scope = mScope.BeginLifetimeScope(b => b.RegisterInstance(Of ILogger)(l))
{
var rr = scope.ResolveKeyed(Of IRealtime)(key)
}

The above gets all the necessary injections including the one ILogger I added in the nested scope.

Thanks

Glenn

Reply all
Reply to author
Forward
0 new messages