How to handle constructor exception when using Autofac WcfIntegration - c#

Is there a way to handle an exception thrown by the constructor of a WCF service, when that constructor takes in a dependency, and it is the instantiation of the dependency by the IoC container (AutoFac in this case) that causes the exception?
Consider a WCF service with the following constructor:
public InformationService(IInformationRetriever informationRetriever)
{
_informationRetriever = informationRetriever;
}
//... the service later makes use of the injected InformationRetriever
The service uses AutoFac WcfIntegration and the AutofacWebServiceHostFactory (this happens to be a RESTful service).
Dependencies are registered in the global.asax.cs of the service, i.e.:
builder.RegisterType<InformationRetriever>()
.As<IInformationRetriever>()
Now the InformationRetriever implementation performs some checks in its constructor to ensure everything is in place for it to be able to do its job. When it discovers a problem in this phase, it throws an exception.
However, I do not want the caller of the service to receive the AutoFac exception:
An exception was thrown while invoking the constructor ... on type InformationRetriever
Effectively I am trying to test:
Given the InformationService is running
When I call the GetSomeInformation() method
And The InformationRetriever cannot be instantiated
Then I want to return a friendly error message
And Log the actual exception
Is this a problem with my design, or is there a known pattern to overcome or prevent this problem?
I have hunted around and could not find any information on this type of problem.

Objects written in the DI style generally pass through two separate phases: composition and execution. The composition phase is where you wire up dependencies and do things like throw argument exceptions. You generally want to keep this phase free of meaningful behavior, as that allows you to surface errors in the configuration of your system. The second phase, execution, is where you use the output of the first phase (dependencies) to do your work.
Separating these two phases removes a lot of ambiguity and complexity. As an example, you don't try to mow your lawn while gassing up your lawnmower; that causes both activities to become more complex (and dangerous!)
In this case, InformationRetriever is conflating the composition and execution phases by performing meaningful work in its constructor. This mixing is causing exactly the issue you are trying to avoid: a meaningful business exception being wrapped in a composition exception. It is also unclear how to handle the exception, since the top-level invoker is Autofac and not the component which is actually asking InformationRetriever to do work.
I suggest striving to do the validation when calling on InformationRetriever; this removes the Autofac exception and allows InformationService to handle the exceptional situation without any trickery.
One potential downside of this approach is that the validation will happen on every call to InformationRetriever, rather than once in the constructor. You have two choices: 1) Let it happen every time, to be absolutely sure the work is valid to do, or 2) Keep track of whether you've done the check and only do it if you haven't before.
If you choose #2, you can keep InformationRetriever clean by using a decorator to wrap it in a validating version of the same interface:
public class ValidatingInformationRetriever : IInformationRetriever
{
private readonly IInformationRetriever _baseRetriever;
private bool _validated;
public ValidatingInformationRetriever(IInformationRetriever baseRetriever)
{
_baseRetriever = baseRetriever;
}
public void Foo()
{
if(!_validated)
{
Validate();
_validated = true;
}
_baseRetriever.Foo();
}
private void Validate()
{
// ...
}
}
You can register it using Autofac's decorator support like so:
builder
.RegisterType<InformationRetriever>()
.Named<IInformationRetriever>("base");
builder.RegisterDecorator<IInformationRetriever>(
(c, inner) => new ValidatingInformationRetriever(inner),
fromKey: "base");

I'm not a big fan of constructors throwing exceptions for reasons other than bad arguments. I'd probably model my types a different way. But here's some ideas. At first I thought about doing something like this:
builder
.Register(c => {
try
{
return new InformationRetriever();
}
catch (Exception)
{
return new FailoverInformationRetreiver();
}})
.As<IInformationRetriever>();
... where FailoverInformationRetreiver throws exceptions on member access. Another idea might be to do:
public InformationService(Lazy<IInformationRetriever> informationRetriever)
{
_informationRetriever = informationRetriever;
}
and try/catch around usages inside InformationService. Another option you could go with if the availability of InformationRetriever is known at app startup:
// inside your container builder:
if (InformationRetreiver.IsAvailable())
builder.RegisterType<InformationRetriever>()
.As<IInformationRetriever>()
// inside InformationService, make the dependency optional
public InformationService(IInformationRetriever informationRetriever = null)
{
_informationRetriever = informationRetriever;
}
Do any of those ideas help?

Related

Register, Resolve, Release pattern usage

I'm currently reading the book Dependency Injection in .NET by Mark Seeman. In this book he recommends the Register, Resolve, Release pattern and also recommends that each of these operations should appear only once in your application's code.
My situation is the following: I'm creating an application that communicates with a PLC (a kind of industrial embedded computer) using a proprietary communication protocol for which the PLC manufacturer provides an library. The library's documentation recommends creating a connection to the PLC and maintaining it open; then using a timer or a while loop, a request should be periodically sent to read the contents of the PLC's memory, which changes over time.
The values read from the PLC's memory should be used to operate on a database, for which I intend to use Entity Framework. As I understand it, the best option is to create a new dbContext on every execution of the loop in order to avoid a stall cache or concurrency problems (the loop could be potentially executing every few milliseconds for a long time while the connection is kept open all the time).
My first option was calling Resolve on application construction to create a long-lived object that would be injected with the PLC communication object and would handle loop execution and keep the connection alive. Then, at the beginning of every loop execution I intended to call Resolve again to create a short-lived object that would be injected with a new dbContext and which would perform the operations on the database. However, after reading the advice on that book I'm doubting whether I'm on the right track.
My first idea was to pass a delegate to the long-lived object upon its construction that would allow it to build new instances of the short-lived object (I believe it is the factory pattern), thus removing the dependency on the DI container from my long-lived object. However, this construct still violates the aforementioned pattern.
Which is the right way of handling Dependency Injection in this situation?
My first attempt without DI:
class NaiveAttempt
{
private PlcCommunicationObject plcCommunicationObject;
private Timer repeatedExecutionTimer;
public NaiveAttempt()
{
plcCommunicationObject = new PlcCommunicationObject("192.168.0.10");
plcCommunicationObject.Connect();
repeatedExecutionTimer = new Timer(100); //Read values from PLC every 100ms
repeatedExecutionTimer.Elapsed += (_, __) =>
{
var memoryContents = plcCommunicationObject.ReadMemoryContents();
using (var ctx = new DbContext())
{
// Operate upon database
ctx.SaveChanges();
}
}
}
}
Second attempt using Poor man's DI.
class OneLoopObject
{
private PlcCommunicationObject plcCommunicationObject;
private Func<DbContext> dbContextFactory;
public OneLoopObject(PlcCommunicationObject plcCommunicationObject, DbContext dbContext
{
this.plcCommunicationObject = plcCommunicationObject;
this.dbContext = dbContext;
}
public void Execute()
{
var memoryContents = plcCommunicationObject.ReadMemoryContents();
// Operate upon database
}
}
class LongLivedObject
{
private PlcCommunicationObject plcCommunicationObject;
private Timer repeatedExecutionTimer;
private Func<OneLoopObject> oneLoopObjectFactory;
public LongLivedObject(PlcCommunicationObject plcCommunicationObject, Func<PlcCommunicationObject, OneLoopObject> oneLoopObjectFactory)
{
this.plcCommunicationObject = plcCommunicationObject;
this.dbContextFactory = dbContextFactory;
this repeatedExecutionTimer = new Timer(100);
this.repeatedExecutionTimer.Elapsed += (_, __) =>
{
var loopObject = oneLoopObjectFactory(plcCommunicationObject);
loopObject.Execute();
}
}
}
static class Program
{
static void Main()
{
Func<PlcCommunicationObject, OneLoopObject> oneLoopObjectFactory = plc => new OneLoopObject(plc, new DbContext());
var myObject = LongLivedObject(new PlcCommunicationObject("192.168.1.1"), oneLoopObjectFactory)
Console.ReadLine();
}
}
The first edition states (chapter 3, page 82):
In its pure form, the Register Resolve Release pattern states that you should only make a single method call in each phase [...] an application should only contain a single call to the Resolve method.
This description stems from the idea that your application only contains either one root object (typically when writing a simple console application), or one single logical group of root types, e.g. MVC controllers. With MVC controllers, for instance, you would have a custom Controller Factory, which is provided by the MVC framework with a controller type to build. That factory will, in that case, only have a single call to Resolve while supplying the type.
There are cases, however, where your application has multiple groups of root types. For instance, a web application could have a mix of API Controllers, MVC Controllers and View Components. For each logical group you would likely have a single call to Resolve, and thus multiple calls to Resolve (typically because each root type gets its own factory) in your application.
There are other valid reasons for calling back into the container. For instance, you might want to defer building part of the object graph, to combat the issue of Captive Dependencies. This seems your case. Another reason for having an extra resolve is when you use the Mediator pattern to dispatch messages to a certain implementation (or implementations) that can handle that message. In that case your Mediator implementation would typically wrap the container and call Resolve. The Mediator’s abstraction would likely be defined in your Domain library, while the Mediator’s implementation, with its knowledge of the container, should be defined inside the Composition Root.
The advice of having a single call to Resolve should, therefore, not be taken literally. The actual goal here is to build a single object graph as much as possible in one call, compared to letting classes themselves call back into the container to resolve their dependencies (i.e. the Service Locator anti-pattern).
The other important point that (the second edition of) the book makes is
Querying for Dependencies, even if through a DI Container, becomes a Service Locator if used incorrectly. When application code (as opposed to infrastructure code) actively queries a service in order to be provided with required Dependencies, then it has become a Service Locator.
A DI Container encapsulated in a Composition Root isn't a Service Locator—it's an infrastructure component.
(note: this quote is from the second edition; Although the first edition contains this information as well, it might be formulated differently).
So the goal of the RRR pattern is to promote encapsulation of the DI Container within the Composition Root, which is why it insists in having a single call to Resolve.
Do note that while writing the second edition, Mark and I wanted to rewrite the discussion of the RRR pattern. Main reason for this was that we found the text to be confusing (as your question indicates). However, we eventually ran out of time so we decided to simply remove that elaborate discussion. We felt that the most important points were already made.
Combining factories with DI is a common solution. There is absolutely nothing wrong with creating and disposing objects dynamically in your program (it's much more difficult and limiting to try to account for every bit of memory you'll need up front).
I found a post by Mark Seeman about the Register, Resolve, Release Pattern (RRR) here: http://blog.ploeh.dk/2010/09/29/TheRegisterResolveReleasepattern/
He states that...
The names originate with Castle Windsor terminology, where we:
Register components with the container
Resolve root components
Release components from the container
So the RRR pattern is limited to the DI Container. You do indeed Register and Release components with the container one time in your application. This says nothing about objects not injected through DI, ie those objects created dynamically in the normal execution of your program.
I have seen various articles use distinct terminology for the two different types of things you create in your program with relation to DI. There are Service Objects, ie those global objects injected via DI to your application. Then there are Data or Value Objects. These are created by your program dynamically as needed and are generally limited to some local scope. Both are perfectly valid.
It sounds like you want to be able to both resolve objects from the container and then release them, all without directly referencing the container.
You can do that by having both a Create and a Release method in your factory interface.
public interface IFooFactory
{
Foo Create();
void Release(Foo created);
}
This allows you to hide references to the container within the implementation of IFooFactory.
You can create your own factory implementation, but for convenience some containers, like Windsor, will create the factory implementation for you.
var container = new WindsorContainer();
container.AddFacility<TypedFactoryFacility>();
container.Register(Component.For<Foo>());
container.Register(
Component.For<IFooFactory>()
.AsFactory()
);
You can inject the factory, call Create to obtain an instance of whatever the factory creates, and when you're done with it, pass that instance to the Release method.
Windsor does this by convention. The method names don't matter. If you call a method of the interface that returns something, it attempts to resolve it. If a method returns void and takes an argument then it tries to release the argument from the container.
Behind the scenes it's roughly the same as if you wrote this:
public class WindsorFooFactory : IFooFactory
{
private readonly IWindsorContainer _container;
public WindsorFooFactory(IWindsorContainer container)
{
_container = container;
}
public Foo Create()
{
return _container.Resolve<Foo>();
}
public void Release(Foo created)
{
_container.Release(created);
}
}
The factory implementation "knows" about the container, but that's okay. Its job is to create objects. The factory interface doesn't mention the container, so classes that depend on the interface aren't coupled to the container. You could create an entirely different implementation of the factory that doesn't use a container. If the object didn't need to be released you could have a Release method that does nothing.
So, in a nutshell, the factory interface is what enables you to follow the resolve/release part of the pattern without directly depending on the container.
Here's another example that shows a little bit more of what you can do with these abstract factories.
Autofac uses Func<> as the factory pattern so you could always do the same:
public class Foo()
{
private readonly Func<Bar> _barFactory;
public Foo(Func<Bar> barFactory)
{
_barFactory = barFactory;
}
}
Adding Factory Interfaces for factories is not something I think anyone should need to do most of the time, it's extra work for little to no reward.
Then you simply need to keep track of which entities are externally owned or DI owned for your release (Dispose in C#).

Inject dependecy into no parameters constructor (Windsor container)

I want to use my child class like this:
throw new MyCustomException()
And I whenever this be invoke I want to wrap it with correlation id which suppose to be injected by the service.
I want to inject it to the base class to avoid writing like that
throw new MyCustomException(correlationID)
but I don't know how to do it in the situation where this should be done with constructor injection.
In other words I want to inject dependency to no parameter constructor. Something like that
class MyBaseException()
{
private IWorkingContext workingContext;
public MyBaseException()
{
this.workingContext = workingContext;
}
}
And yes, I know that normally I need to do it like this:
public MyBaseException(IWorkingContext workingContext)
But want this constructor MyBaseException(IWorkingContext workingContext) to be invoked without parameteres so in the end I could use my child class like MyCustomException() and have the workingContext wrapped in it.
My Windsor registration:
container.Register(Component.For<IWorkingContext>().ImplementedBy<WorkingContext>().LifeStyle.PerWebRequest)
I've tried this approach:
var containerAccessor = HttpContext.Current.ApplicationInstance as IContainerAccessor;
var container = containerAccessor.Container;
var operationContext = container.Resolve<IWorkingContext>();
but it doesn't work (new object is created by Windsor).
The moment you new up an exception - or any class for that matter - it is not managed by your IOC container, so it simply can't help you enrich your exception class.
There are a couple of things you can do, however, some of them of questionable quality:
Use a service locator pattern in the constructor of your exception (very yucky)
Use a factory method/class - registered in your IOC container with a dependency on IWorkingContext - which will actually give you an instance of your exception to throw up the stack. This still means that your exception would have a constructor accepting in a dependency, but the class throwing the exception doesn't know or need to know this. (I would recommend this approach)
A dedicated class, living on the periphery of your domain, designed to catch and subsequently enrich any exceptions bubbling up the stack. This is risky for several reasons:
An incorrect implementation will have you lose the context of the exception (stack trace information mainly)
You are now pretty much enforcing every component to ignore exceptions, as you desperately need that context on the exceptions for logging purposes or what not.
Question the entire approach you're going for. Why not enrich the exceptions at log time with the context, instead of adding this metadata at exception time?
Personally, I'd look at 2 as the most viable option, but it can grow out of control quickly if you have a lot of different custom exceptions throughout your application. I would always look at 4, regardless of which option you go for because sometimes the problem you're trying to solve is the wrong problem.

How to implement this mixed object Lifetime with Simple Injector

I'd like to know how to register the classes and setup a Simple Injector container to instantiate the classes in the following way. ie go from manual DI to having the below Consumer class have the CompositeService injected and the object graph and lifetimes setup as follows:
To bring some context (if it helps) the Consumer class might be a ViewModel from a WPF application which gets instantiated when the View is requested.
public class Consumer
{
public Consumer()
{
var sharedSvc = new SharedService();
var productSvc = new ProductService(sharedSvc, new MathHelper());
var compositeSvc = new CompositeService(sharedSvc, productSvc, new MathHelper());
compositeSvc.Process();
}
}
where:
MyContext should be shared within the scope of the calls.
ProductService and CompositeService can be transient or shared within the scope.
MathHelper must be transient.
Q: How can the above be achieved with Simple Injector?
OR more specifically:
How can I instantiate multiple MathHelpers within the context of the Simple Injector Scope?
I've read up on http://simpleinjector.readthedocs.org/en/latest/lifetimes.html
and read and followed the SO answer https://stackoverflow.com/a/29808487/625113 however,
it seems either everything can be transient or scoped but not certain specific objects scoped and the rest transient (which seems odd).
Update 1
The following with Simple Injector will achieve the SharedService result, but if I want ProductService and CompositeService to also have a scoped lifetime it wont work:
cont.RegisterLifetimeScope<SharedService>();
cont.Register<MathHelper>();
cont.Register<ProductService>();
cont.Register<CompositeService>();
using (cont.BeginLifetimeScope())
{
var compositeSvc = cont.GetInstance<CompositeService>();
compositeSvc.Process();
}
If I register either or both of the ProductService or CompositeService as RegisterLifetimeScope I get a Lifetime mismatch exception. ie
cont.RegisterLifetimeScope<SharedService>();
cont.Register<MathHelper>();
cont.RegisterLifetimeScope<ProductService>();
cont.Register<CompositeService>(); // or cont.RegisterLifetimeScope<CompositeService>();
using (cont.BeginLifetimeScope())
{
var compositeSvc = cont.GetInstance<CompositeService>(); // Exception thrown
compositeSvc.Process();
}
Throws an exception leading to this page: https://simpleinjector.readthedocs.org/en/latest/LifestyleMismatches.html
I can under that in relation to Singleton should be dependent on Transient and can infer a sort of understanding that the same could be said in this case that Simple Injector is warning that Scoped can't depend on Transient because Transient isn't managed within the scope.
So my question is more specifically how can I instantiate multiple MathHelpers within the context of the Simple Injector Scope?
Update 2 - Further background and example
Brief background - This situation arose as I have a 4 year old, 2-tier, WPF based application currently using Ninject which has the bloated mixed Service architecture that #Steven describes
in his blog series (ie the Services have become a mash of mixed, semi-related, command and queries). Most of these services are a good candidate for separating out into
ICommandHandler/IQueryHandler architecture...but you can't do things overnight, so first crack was to convert from Ninject to SimpleInjector (yes I know Ninject can do the same thing in regards to this architecture
but there are other reasons for moving to SimpleInjector).
As far as "scoping" the dependency resolution, a "scope" (in this application) is considered to be for the life of a form so one DbContext (like the SharedService in the example above) is shared amoungst the
services that the form/viewModel require and MOST of the services are per scope with some injected services or helper classes needing to be injected as Transient.
This (to me) is analogous to Mark Seemann's hand-coded example from http://blog.ploeh.dk/2014/06/03/compile-time-lifetime-matching/ where he has a Per Request (singleton-scoped) service which has
Transient objects injected into it.
Edit: I had misread Mark Seemann's example and was reading the code as if the BarController were a service. So whilst the BarController object composition is the same the lifetime is not. That said the SomeThreadUnsafeService could just as easily have a new SomeServiceThatMustBeTransient injected into it but, I stand corrected, his example doesn't do this.
Hence I was wanting to know how to do the object composition Mark Seemann does in Simple Injector but outside the context of web reqeusts (my assumption is that Simple Injector's
Per web request scoping is in essence a specific type of Lifetime Scoping).
To address #Steve and #Ric .net's comment and answer, I can see that there is the potential to end up with the scenario where 2 different services use another, shared service that uses a transient object (storing state) and the supposedly transient object becomes a
Singleton Scoped object in the context of "some" of those services. eg
public class SingletonScopedService1
{
private readonly TransientX _transientA;
public SingletonScopedService1(TransientX transientA)
{
_transientA = transientA;
}
public void PokeTransient()
{
_transientA.Poke();
}
}
public class SingletonScopedService2
{
private readonly SingletonScopedService1 _service1;
private readonly TransientX _transientB;
public SingletonScopedService2(SingletonScopedService1 service1, TransientX transientB)
{
_service1 = service1;
_transientB = transientB;
}
public void GoFishing()
{
_service1.PokeTransient();
// This TransientX instance isn't affected
_transientB.Poke();
}
}
public class SingletonService3
{
private readonly SingletonScopedService1 _service1;
public SingletonService3(SingletonScopedService1 service1)
{
_service1 = service1;
}
public void DoSomething()
{
_service1.PokeTransient();
}
}
If DoSomething() is called on SingletonScopedService3 and GoFishing() is called on SingletonScopedService2 (and assuming TransientX maintains state) then results "may" be unexpected depending on the purpose of TransientX.
So I'm happy to accept this since the application is operating as expected (but also accept that the current composition is fragile).
With that said, can my original composition or Mark Seemann's example be registered with Simple Injector with the required life-times or is it strictly not possible by design and better to manually compose the object
graph (or inject a Func as #Ric .net suggests) for the instances where this is required until further refactoring/hardening can be done?
Update 3 - Conclusion
Whilst Ninject allows you to register my original composition like:
var kernel = new StandardKernel();
kernel.Bind<SharedService>().ToSelf().InCallScope();
kernel.Bind<MathHelper>().ToSelf();
kernel.Bind<ProductService>().ToSelf().InCallScope();
kernel.Bind<CompositeService>().ToSelf().InCallScope();
Simple Injector by design does not and I believe my second example is an example as to why.
FYI: In my real-world case, for the few instances that the object graph had this, I've manually constructed the graph (just to get switched to Simple Injector) with the intent on refactoring these potential issues out.
As explained in the linked SO question what the Lifestyle Mismatch exception is basically saying is that you're creating a so called captive dependency when you let a object depend on another object which has a shorter lifestyle.
While it maybe sounds odd to you, a captive dependency is:
A real life problem which, if undetected, would typically lead to very strange bugs which are very hard to debug
A sign, as indicated by Steven, that the service has some kind of state which is never a good sign
If MathHelper has mutable state and therefore needs to be injected in other services as transient, MathHelper has become some sort of 'runtime data'. And injecting runtime data is an anti-pattern.
This blogpost describes in detail what the problem is with runtime data and how to solve this. Solving your problem as described there is the way to go!
Because you did not specify the implementation details of MathHelper, it is hard to give you some advice how you should refactor MathHelper. So the only advice I can give you is, let runtime data or 'state' flow through the system as messages. You can read about message based design here and here.
There are however several other options, which will work but aren't good design IMO. So the advice is not to use these, but to be complete:
Instead of injecting MathHelper as a transient you could inject a MathHelperProvider or even simpler inject a Func<MathHelper> which you could register as singleton:
container.RegisterSingleton<Func<MathHelper>>(() => container.GetInstance<MathHelper>());
Notice that by registering a delegate you will make the container blind. It won't be able to warn you of misconfigurations in this part of the object graph anymore.
The other solutions I had in mind are so ugly in its design, that after writing them, I decided to leave them out of this answer!
If you would add some details about why MathHelper needs to be transient, I could give you some advice where you could make adjustments to make it scoped or even better: singleton.

StructureMap and objects not setup for DI/IoC

I have a situation where I've created a factory method to create an object. However, the object has boilerplate code that needs execution before the object is created. Fixing that part of the design is out of scope for this question.
Also, when the object is created, a status display is updated on screen. This requires that this status display be instantiated before and be visible and the application be in a running state before creating this object. It is passed to the factory as a dependency.
I'm using v3.1.4.143 of StructureMap.
So, here's what I'd be doing in the normal world (pre-IoC):
GraphicsInterface GetGraphics()
{
VideoDevicesList.GetVideoDevices();
// Some logic here to determine the device to use...
// Also, a status display is being updated to inform the user of
// what's happening at this point.
VideoDevice device = ...;
// The second parameter is a constant value, but the first is not.
return new GraphicsInterface(device, featureLevels.FL5);
}
Seems simple enough, but ideally I'd like to be able to pass that graphics object around via injection as it'll be needed in many spots.
So, in structure map, I created a factory function to do the above. However it's giving me grief.
new Container(obj =>
{
// This is passed to the object that depends on it.
// I've just left it out for brevity.
// It'd go something like: _graphics = _getGraphicsFactory();
// where _getGraphicsFactory is the factory function below.
For<Func<IStatusDisplay, GraphicsInterface>>
.Use<Func<IStatusDisplay, GraphicsInterface>>(GetGraphics);
}
Only this gives me an error about GraphicsInterface not being registered. That's fine, I should be able to register the GraphicsInterface object. Except that I can't register GraphicsInterface because the constructor requires two parameters, one of which must be queried before creating the object and can only be set up via the GetVideoDevices method above and it seems StructureMap tries to create the object for me when I call _getGraphicsFactory() (which is weird, I would have it expected it to execute my function to create the object).
I tried even calling GetInstance like this inside of my GetVideoDevices method:
_container
.With<VideoDevice>(device)
.With<FeatureLevel>(FeatureLevel.FL5)
.GetInstance<Graphics>();
But no dice...
So, does anyone have an idea on how I'd get this to work?
Whenever you are scratching your head trying to work out how to create instances at runtime, you need to step back and look for a design pattern that will fit the problem. DI is meant for composing applications, but controlling runtime behavior should be part of the application design - that is, the part that runs after the application is composed.
In this particular case, Abstract Factory would be a good fit. It allows you to separate the composed services (those injected through the constructor) from runtime services (those passed as method parameters).
However, you should restrict a factory to doing exactly one thing - creating the runtime instance. All other work should be part of other services. This gives you a clean way to inject a runtime object into your service and still allow the service behavior to be tested independently of this step.
public interface IGraphicsFactory
{
GraphicsInterface Create(VideoDevice device);
void Release(GraphicsInterface graphicsInterface);
}
public class GraphicsFactory : IGraphicsFactory
{
private readonly FeatureLevel featureLevel;
// Parameters injected are done so by the DI container
public GraphicsFactory(FeatureLevel featureLevel)
{
this.featureLevel = featureLevel;
}
// Parameters passed are part of the application runtime state
public GraphicsInterface Create(VideoDevice device)
{
return new GraphicsInterface(device, this.featureLevel);
}
// Method for releasing disposable dependencies (if any)
public void Release(GraphicsInterface graphicsInterface)
{
var disposable = graphicsInterface as IDisposable;
if (disposable != null)
disposable.Dispose();
}
}
Your factory can then be supplied to a service during application composition, and runtime instances of GraphicsInterface can be created at runtime. As per your requirement, this can easily be done in multiple spots by injecting it into the constructors of multiple services.
public class SomeService : ISomeService
{
private readonly IGraphicsFactory graphicsFactory;
public SomeService(IGraphicsFactory graphicsFactory)
{
if (graphicsFactory == null)
throw new ArgumentNullException("graphicsFactory")
this.graphicsFactory = graphicsFactory;
}
public void DoSomething()
{
// Get video device here. It will likely be best to
// delegate that to another specialized service
// that is injected into this class.
VideoDevice device = ...;
var graphics = this.graphicsFactory.Create(device);
try
{
// Do something with graphics
}
finally
{
this.graphicsFactory.Release(graphics);
}
}
}
As for selecting the device to use, that could either be done with another Abstract Factory, or if it is something that is done often, you could use a Strategy Pattern to load all of the options at composition time, and then selectively choose the device at runtime. Or, if your devices are disposable, you could make a Strategy of Abstract Factories or look to some more advanced design pattern to clean them up.
You might also consider using an adapter pattern to create an abstraction for GraphicsInterface if it doesn't already have a suitable that can be injected (and swapped) that has all of the members you are after.
public interface IGraphicsInterfaceAdapter
{
// Extract all public properties of GraphicsInteface and define them here.
}
public class GraphicsInterfaceAdapter : IGraphicsInterfaceAdapter
{
public GraphicsInterfaceAdapter(VideoDevice device, FeatureLevel featureLevel)
: base(device, featureLevel)
{
}
}

How do I detect and log the parameter names and values in the method signature of a delegate?

Thanks for looking!
Background
I have an extension method that is used to wrap a given method in a try/catch and I am adding code for logging any caught exceptions:
public static T HandleServerError<T>(this Func<T> func)
{
T result = default(T);
try
{
result = func();
}
catch (Exception ex)
{
//******************************
//Code for logging will go here.
//******************************
ErrorHandlers.ThrowServerErrorException(ex);
}
return result;
}
Here is how the method is called:
var result = new Func<SomeClass.SomeType>(() => SomeClass.SomeMethod(id, name, color, quantity)).HandleServerError();
return result;
As you can see, whatever method I am calling is injected into the extension method and executed inside the try/catch.
We will be using NLog or ELMAH for logging, but that is largely irrelevant to this question.
Problem
If something goes wrong, I need to log as much information about the delegated method as possible since things like "Object reference not set to an instance of an object" is not in itself helpful.
I would like to log the class and name of the method being called as well as the parameters in the method signature along with their values. If possible, I would even like to log which line failed, and finally the actual stack trace.
I am guessing that I need to use reflection for this and maybe catch the binding flags somehow as the injected method executes but I am not entirely sure if that is the best approach or if it is even feasible.
Question
Using C#, how do I get the meta information (i.e. method name, class of origin, parameters, parameter values) about an injected/delegated method?
Thanks in advance.
It seems to me that there is a possibility for you to improve the way you are adding this logging cross-cutting concern to your application.
The main issue here is that although your solution prevents you from making any changes to SomeClass.SomeMethod (or any called method), you still need to make changes to the consuming code. In other words you are breaking the Open/closed principle, which tells us that it must be possible to make these kinds of changes without changing any existing code.
You might think I'm exaggerating, but you probably already have over a hundred calls to HandleServerError in your application, and the number of calls will only be growing. And you'll soon add even more of those 'functional decorators' to the system pretty soon. Did you ever think about doing any authorization checks, method argument validation, instrumentation, or audit trailing? And you must admit that doing new Func<T>(() => someCall).HandleServerError() just feels messy, doesn't it?
You can resolve all these problems, including the problem of your actual question, by introducing the right abstraction to the system.
First step is to promote the given method arguments into a Parameter Object:
public SomeMethodParameters
{
public int Id { get; set; }
public string Name { get; set; }
public Color Color { get; set; }
public decimal Quantity { get; set; }
public decimal Result { get; set; }
}
Instead of passing all the individual arguments into a method, we can pass them all together as one single object. What's the use of that, you may say? Read on.
Second step is to introduce a generic interface to hide the actual logic of the SomeClass.SomeMethod (or in fact any method) behind:
public interface IMethodHandler<TParameter>
{
void Handle(TParameter parameter);
}
For each (business) operation in the system, you can write an IMethodHandler<TParameter> implementation. In your case you could simply create an implementation that wraps the call to SomeClass.SomeMethod, like this:
public class SomeMethodHandler
: IMethodHandler<SomeMethodParameters>
{
void Handle(SomeMethodParameters parameter)
{
parameter.Result = SomeClass.SomeMethod(
parameter.id,
parameter.Name,
parameter.Color,
parameter.Quantity);
}
}
It might look a bit silly to do things like this, but it allows you to implement this design quickly, and move the logic of the static SomeClass.SomeMethod inside of the SomeMethodHandler.
Third step is let consumers depend on a IMethodHandler<SomeMethodParameters> interface, instead of letting them depend on some static method in the system (in your case again the SomeClass.SomeMethod). Think for a moment what the benefits are of depending on such abstraction.
One interesting result of this is that it makes it much easier to unit test the consumer. But perhaps you're not interested in unit testing. But you are interested in loosely coupling. When consumers depend on such abstraction instead of a real implementation (especially static methods), you can do all kinds of crazy things, such as adding cross-cutting concerns such as logging.
A nice way to do this is to wrap IMethodHandler<T> implementations with a decorator. Here is a decorator for your use case:
public class LoggingMethodHandlerDecorator<T>
: IMethodHandler<T>
{
private readonly IMethodHandler<T> handler;
public LoggingMethodHandlerDecorator(
IMethodHandler<T> handler)
{
this.handler = handler;
}
public void Handle(T parameters)
{
try
{
this.handler.Handle(parameters);
}
catch (Exception ex)
{
//******************************
//Code for logging will go here.
//******************************
ErrorHandlers.ThrowServerErrorException(ex);
throw;
}
}
}
See how the Handle method of this decorator contains the code of your original HandleServerError<T> method? It's in fact not that much different from what you were already doing, since the HandleServerError 'decorated' (or 'extended') the behavior of the original method with new behavior. But instead of using method calls now, we're using objects.
The nice thing about all this is, is that this single generic LoggingMethodHandlerDecorator<T> can be wrapped around every single IMethodHandler<T> implementation and can be used by every consumer. This way we can add cross-cutting concerns such as logging, etc, without both the consumer and the method to know about this. This is the Open/closed principle.
But there is something else really nice about this. Your initial question was about how to get the information about the method name and the parameters. Well, all this information is easily available now, because we've wrapped all arguments in an object instead of calling some custom method wrapped inside a Func delegate. We could implement the catch clause like this:
string messageInfo = string.Format("<{0}>{1}</{0}>",
parameters.GetType().Name, string.Join("",
from property in parameters.GetType().GetProperties()
where property.CanRead
select string.Format("<{0}>{1}</{0}>",
property.Name, property.GetValue(parameters, null)));
This serializes the name of the TParameter object with its values to an XML format. Or you can of course use .NET’s XmlSerializer to serialize the object to XML or use any other serialization you need. All the information if available in the metadata, which is quite nice. When you give the parameter object a good and unique name, it allows you to identify it in the log file right away. And together with the actual parameters and perhaps some context information (such as datetime, current user, etc) you will have all the information you need to fix a bug.
There is one difference between this LoggingMethodHandlerDecorator<T> and your original HandleServerError<T>, and that is the last throw statement. Your implementation implements some sort of ON ERROR RESUME NEXT which might not be the best thing to do. Is it actually safe to continue (and return the default value) when the method failed? In my experience it usually isn't, and continuing at this point, might make the developer writing the consuming class think that everything works as expected, or might even make the user of the application think that everything worked out as expected (that his changes were saved for instance, while in fact they weren't). There's usually not much you can do about this, and wrapping everything in catch statements only makes it worse, although I can imagine that you want to log this information. Don’t be fooled by user requirements such as “the application must always work” or “we don’t want to see any error pages”. Implementing those requirements by suppressing all errors will not help and will not fix the root cause. But nonetheless, if you really need to catch-and-continue, just remove the throw statement`, and you'll be back at the original behavior.
If you want to read more about this way of designing your system: start here.
You can simply access its Method and Target properties as it's basically any other delegate.
Just use func.Method and func.Target.

Categories