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.
Related
I am pretty new to C# and I'm having trouble figuring out how to get dependency injection to work when instantiating a new class.
I have an Error class that I use to store basic information about errors, warnings, etc when using Quartz to pass to the UI when something happens with the job. We also want to use the Serilog inside those errors to log in case something happens.
How would I use dependency injection with my Error class to use ILogger (Serilog) when creating a new Error class.
The JobClass that we use has DI with the ILogger. ( I don't know if this matters)
When I do
Error e = new Error();
it wants me to pass the ILogger as parameter.
When I do Error e = new Error(); it wants me to pass the ILogger as parameter.
Well, yeah, you're trying to call a constructor directly, it has to be correct C# code. Dependency injection is at the framework level, not the language level.
With that in mind, if you want to construct an object with DI, you have to ask your framework to construct it for you, with something similar to:
var error = services.GetRequiredService<IError>();
And have your error class implement that interface and register it as a transient dependency (ie, get a new one every call).
I want to stress however that you shouldn't be doing this, DI spreads virally for you. If you want one of these things created for you, simply add an IError parameter to your controller constructor and you'll get sent one on object creation to do whatever you want with it.
I have a requirement to completely delete an instance that is already resolved by DryIoC container (but not unregister the type). I don't know if this is possible?
If I don't use any IoC container and just declare singletons myself I of course can reset it to null easily whenever I want.
e.g:
var instance = DryIocContainer.Resolve<SomeType>();//a singleton
//All next times calling Resolve<> will return just that singleton instance.
//But if that is cleared, the next time calling Resolve<> should create
//a completely new instance (like as the first time it was called).
The scenario here is after user logging off my app, I want to clear all resolved singletons so that if the user logging back using another account (or even with that same account), the data will be refreshed correctly. Currently without being able to clear those singletons, I have to reset all properties manually myself - which I think should just be the last resort.
I don't know if this is possible?
No, this isn't really possible. Although Dadhi pointed to the WithoutSingletonsAndCache method, this effectively builds up a new container with a new set of instances. Although this allows you to replace your particular singleton, it also means that all other singleton registrations will be cleared and you lose the promise of there being only one instance of a particular type. In other words, in able to do this, the container has broken its promise around singletons. This effectively leads to a Torn Lifestyle. You will have closely analyse whether or not this will be a problem or not.
If I don't use any IoC container and just declare singletons myself I of course can reset it to null easily whenever I want.
This is not true. Even without a container, you can't simply replace a singleton. A simple example is when this singleton to be replaced is a dependency of another singleton. Unless you replace that singleton (and all its singleton consumers up the chain), this original instance is captured within its consumer and will the consumer will keep referencing the original instance, even though you try to replace it. This is a form of the Captive Dependency problem.
The only true way to solve this problem, and solve it locally for this instance only, is to create a Proxy for the abstraction of that Singleton. This proxy can wrap that dependency and you can allow it to be changed later on. This allows you to at any moment in time replace the dependency.
How to implement this, does highly depend on your particular needs, but here's an example:
public interface ISomeType
{
void SomeMethod();
}
public class SomeTypeImpl : ISomeType { ... }
public class SomeTypeProxy : ISomeType
{
public ISomeType Dependency { get; set; }
public SomeTypeProxy(ISomeType dependency) {
this.Dependency = dependency;
}
public void SomeMethod() => this.Dependency.SomeMethod();
}
Without a DI container, you can use this as follows:
var proxy = new SomeTypeProxy(new SomeTypeImpl());
// later on
proxy.Dependency = new OtherTypeImpl();
Another option is to let the Proxy wrap a Func<T> delegate, which allows you to move this logic to the delegate:
ISomeType dependency = new SomeTypeImpl();
var proxy = new SomeTypeProxy(() => dependency);
// later on
dependency = new OtherTypeImpl();
The scenario here is after user logging off my app, I want to clear all resolved singletons so that if the user logging back using another account
In your particular case, you are actually describing clearing the complete application. Your scenario sounds similar to restrarting the application. This is probably something that WithoutSingletonsAndCache works good at, because you wish to reset all singletons.
The same however can be achieved with just creating a new container with all its registrations. Your application will already have some sort of CreateContainer class, and it should be a matter of calling that CreateContainer method again.
Of course this method only works when your dealing with an application at only handles one user, instead of having a web application that runs requests for many users concurrently.
You can do:
container = container.WithoutSingletonsAndCache();
Here is the docs.
I'm converting my code to use an IoC Container with StructureMap. Trying to get my head around things, and I feel it's starting to 'click' and I can see how it makes so much sense with the back-end side.
However, I'm working my way down I've spotted a few sitautions where I'm not sure how to make it work. Specifically, the case where my original constructor did something important with an argument that isn't really a dependency, or something that will change at run-time.
Let's say I start with this (pre IoC Container), where I was passing my dependencies using a constructor, but also sending it an ImportantObject that's run-time dependent:
IMyPageViewModel myPageViewModel = new MyPageViewModel(importantObject, dialogManager, pageDisplay, viewModelProvider)
and here it is doing its constructing:
public MyPageViewModel(ImportantObject importantObject, IDialogManager dialogManager,IPageDisplay pageDisplay, IViewModelProvider viewModelProvider)
{
this.dialogManager = dialogManager;
this.pageDisplay = pageDisplay;
this.viewModelProvider = viewModelProvider;
importantObject.DoThatImportantThing();
}
Now, I'm migrating to use the IoC container, and at first I think I should do something like this:
//I need to create an instance to use, so I use my IoC container:
IMyPageViewModel myPageViewModel = container.GetInstance<IMyPageViewModel>();
then letting it resolve it's dependencies, however importantObject is something that's set at runtime. I can't register it as a dependency:
public MyPageViewModel(IDialogManager dialogManager,IPageDisplay pageDisplay, IViewModelProvider viewModelProvider, IContainer container)
{
this.dialogManager = dialogManager;
this.pageDisplay = pageDisplay;
this.viewModelProvider = viewModelProvider;
//however, here I have no access to the important object that I previously passed in my constructor
importantObject.DoThatImportantThing(); //obviously error
}
I thought maybe I should be creating using 'new', and passing the IoC container:
IMyPageViewModel myPageViewModel = new MyPageViewModel(importantObject, container)
then letting it resolve it's dependencies in the constructor:
public MyPageViewModel(ImportantObject importantObject, IContainer container)
{
this.dialogManager = container.GetInstance<IDialogManager>();
this.pageDisplay = container.GetInstance<IPageDisplay>();
this.viewModelProvider = container.GetInstance<IViewModelProvider>();
importantObject.DoThatImportantThing();
}
But that strikes me as not a good idea, specifically, I can't run it with a test register and have it create a dummy/stub "MyPageViewModel" for unit testing.
The only other thing I can think of is to remove all the logic from the constructor and putting it in an initialize method, or property setters. However, this means I have to ensure that initialize is always called before use and it will hide errors/problems.
Are any of these options sensible, how should I manage passing a run-time dependent object in a constructor with Dependency Injection?
I tried to stray away from static factories, as I've read lots about them being anti-pattern/bad practice.
Edit: In response to Bruno Garcia's answer I decided to use a factory type pattern that holds the container and deals with object creation like this:
class PageProvider : IPageProvider
{
public MyPageViewModel GetMyPage(ImportantObject importantObject)
{
//might just get, if it's a single only instance
return MyPageViewModel(ImportantObject importantObject,
container.GetInstance<IDialogManager>(),
container.GetInstance<IPageDisplay>(),
container.GetInstance<IViewModelProvider>())
}
}
StructureMap supports passing arguments to Resolve. This could help you with passing the ImportantObject to the Service you are resolving.
It's worth noting that if you pass your container around, things can get really messy really fast. Avoid using it as a Service Locator.
Ideally you'd use the container to resolve an entry point (e.g: Controller, Consumer worker) and from that point on, there's no direct use of the container anymore. If you need to control the lifetime of the dependencies you are taking into your constructor, there are a number of ways to go about that like:
Taking a Factory or a Func<>.
I suggest you reading carefully the docs of the Container you want to use to understand who controls the lifetime of objects (if a Component implements IDisposable, who's going to dispose it?). When are lifetime scopes created/disposed?
IoC Container's are great but it's very easy to find yourself troubleshooting memory leaks if you don't carefully understand the concept of lifetime ownership.
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.
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?