How to easily tell if Ninject can resolve a class - c#

I'm introducing Ninject into a large mess of a existing project. I want to write a diagnostic test to make sure that all of the classes Ninject will end up creating can actually BE resolved by Ninject...without actually creating any of them.
The reason I want to avoid the actual construction is that many of these classes have a tendency to start up database operations in their constructors (sigh yes I know). Otherwise I would just run them all through Get<T> with a try/catch

There's a CanResolve extension on IResolutionRoot (i.e., you can use it against Kernel if you have the right usings in place). There's a CreateRequest that you use to create the request. Have a look in the sources and tests if you need an example or any deeper information.

I know this is an old post but it was the first one I found when searching for how to find if a class can be resolved by Ninject without actually calling get() and risking an exception.
Ninject version 3.0.2 have a method CanResolve which returns a boolean:
kernel.CanResolve<T>()
I got 3.0.2 from nuget but its currently market unstable (Ninject.3.0.2-unstable-9037) so I'm not sure if I use this in production just yet.

Related

Autofac 6 - register decorators conditional on the availability of another service

Before v6, if I wanted to register a decorator depending on the availability of another service - not depending on other decorators applied -, I could do something like:
builder.RegisterType<ApiClientMetricsDecorator>()
.As(new DecoratorService(typeof(IApiClient)))
.OnlyIf(b => b.IsRegistered(new TypedService(typeof(IApiCallMetricsReceiver))));
This does not work anymore. The decorator is not being applied. The reason for this seems to be that internally now the new v6 middleware mechanism is used for decorators.
The existing .RegisterDecorator overloads allow only to pass in a Func<IDecoratorContext, bool>, but IDecoratorContext does not let me check whether a service has been registered, it's only for inspecting the decorator chain and the target instance.
Unfortunately, I cannot just create another local extension method by replicating the source of RegisterDecorator and adjusting as I need because it turns out that the type DecoratorMiddleware is internal.
So what is the way to achieve what I need with v6? Currently the only way I can think of would be to register the decorator always and do another registration:
builder.RegisterType<NullApiCallMetricsReceiver>()
.As<IApiCallMetricsReceiver>()
.IfNotRegistered(typeof(IApiCallMetricsReceiver));
But this would be a very ugly workaround because I would completely unnecessarily add a decorator that does nothing.
If it's relevant, the reason why I need this is because the above registration of the decorator resides in a module in an assembly that is being used by different projects and only in some of these, metrics are relevant and so they register a type providing IApiCallMetricsReceiver.
I got the same pattern multiple times in my code base.
Any help would be greatly appreciated, this is currently keeping me from upgrading to Autofac v6, and I hate being not up-to-date with core libraries like Autofac.
This is a really good question. Unfortunately, I don't think I'm going to have a satisfactory answer:
In Autofac v6... you can't really do what you want. Right now. For the reasons you mentioned - it's not just about services now, it's about managing the resolution pipeline.
But! I have filed an issue on your behalf to get OnlyIf support for decorators in place. We just recently implemented some internals changes that would allow this to happen, so it's pretty good timing.
I don't have a deadline/ETA on when this will be delivered, but it's on the radar. You can subscribe to the issue to follow along if you like.

Disposing of EF DbContext with ninject, when moving away from using statements

I am working with SQL server 2008, .NET4.5, MVC4, EF6 and Ninject3.2.
I have application that needs to be migrated to use DI with Ninject. DbContext that has to be injected in to Controllers is OnlineLegal.
Currently it is used following in each of Actions.
using (var db = new OnlineLegal())
{
...
}
This makes it clearly visible where OnlineLegal is being used and disposed of.
If I would set up ninject kernel.Bind<OnlineLegal>().ToSelf().InRequestScope(); would this be sufficient to make sure that it is disposed properly on each request in MVC4? If not should I manually register OnePerRequestModule? Or use some other way to do it?
It is sufficient. Provided you have installed the Ninject.MVC4 package ;-).
However, there's recently been quite a few question about InRequestScope not working. I think currently the ninject setup is a bit error prone to mistake and/or issues with package installation/upgrade routines.
As such i would recommend to use .InRequestScope() but also add one (exemplar and automated) integration test which verifies that .InRequestScope() actually properly performs the disposal.
That will show you that you've integrated it correctly and if in future there should be trouble with package upgrade routines you'll find out immediately and can fix it, rather than finding out in production or through some obscure effects.
Documentation link: https://github.com/ninject/Ninject.Web.Common/wiki/InRequestScope
Ninject.MVC4 depends on Ninject.Web.Common.Webhost. Ninject.Web.Common.WebHost adds NinjectWebCommon.cs code to your application's app_start folder.
NinjectWebCommon.cs loads the OnerPerRequestModule. However if you remove that file you will break .InRequestScope(). The bad thing about this is, that it fails without exception. You can still bind .InRequestScope() but it just won't have any effect.

IoC and "hiding implementation details"

I implemented DI in my project through constructor injection, now the composition root is where all resolving takes place (this is, at the web project), and my question is whether the idea of creating an additional project that just handles the resolving is insane.
The reasoning behind this is while I would still have the implementation assemblies in the build directory (because they would still be referenced by the "proxy" project), I wouldn't need to reference them at web project level, which in turn would mean that the implementation of these interfaces wouldn't be accessible from somewhere other than where they're implemented (unless explicitly referenced, which would quickly pinpoint that something is wrong: you don't want to be doing this).
Is this a purposeless effort likely to become error prone or is it a reasonable thing to do?
There are pros and cons of this. As BrokenGlass said, this is a litmus test, on the flip side you really have to be careful you deploy all of the assemblies. Since dependencies of included libs are not put into the bin folder of the web app, you'll need to ensure they aren't missed although upon first run you would experience this and the resolution would ideally be easy.
This is indeed a matter of personal preference, for ease I like to include in the web app, but again, it can ensure those dependencies don't leak to the web app. However if your project is organized in such as way where your controllers always inject what you require, then the chances of it happening are less. For ex, if you take IContext in every controller then you are less likely to use using(var context = new Context()) in your app, since the standard has been set.
This is not insane at all - it is a very good litmus test to make sure no dependencies have sneaked in and very useful as such. This would only work though if your abstractions / interfaces are defined in a different assembly than the concrete classes that implement those interfaces.
Having said that, personally I have always kept the aggregate root within the main web app assembly, there is extra effort involved in this extra assembly and since I for the most part only inject interfaces I am not too worried about it, since my main concern is really testability. There might be projects though for which this is a worthwhile approach.
You could do some post-build processing to ensure the implementation doesn't leak out.
Cheers
Tymek

Simplest, fastest way to break out all dependencies from a class

When working with legacy code, and trying to create tests, I often break out dependencies from classes or methods so I can write unit tests using mocks for these dependencies. Dependencies most often come in the form of calls to static classes and objects created using the new keyword in the constructor or other locations in that class.
In most cases, static calls are handled either by wrapping the static dependency, or if its a singleton pattern (or similar) in the form of StaticClass.Current.MethodCall() passing that dependency by its interface go the constructor instead.
In most cases, uses of the new keyword in the constructor is simply replaced by passing that interface in the constructor instead.
In most cases, uses of the new keyword in other parts of the class, is handled either by the same method as above, or by if needed create a factory, and pass the factory's interface in the constructor.
I always use Resharpers refactoring tools to help me all of these break-outs, however most things are still manual labour (which could be automated), and for some legacy classes and methods that can be a very very tedious process. Is there any other refactoring plugins and/or tools which would help me in this process? Is there a "break out all depencencies from this class in a single click" refactoring tool? =)
It sounds to me like all these steps are common for many developers and a common problem, and before I attempt writing plugin to Resharper or CodeRush, I have to ask, because someone has probably already attempted this..
ADDED:
In reflection to answers below: even if you might not want to break out everything at once (one click total break out might cause more problems than it helps) still being able to simply break out 1 methods dependencies, or 1-2 dependencies easily, would be of big difference.
Also, refactoring code has a measure of "try and see what happens just to learn how everything fits together", and a one click total break out would help that process tons, even if you dont check that code in..
I don't think there is any tool that can automate this for you. Working with legacy code means -as you know- changing code with little steps at a time. The steps are often deliberately small to prevent errors from being made. Usually the first change you should make is one that makes that code testable. After you've written the test you change that part of the code in such way that you fix the bug or implement the RFC.
Because you should take small steps I believe it is hard to use a refactoring tool to magically make all your dependencies disappear. With legacy systems you would hardly ever want to make big changes at once, because the risk of breaking (and not finding out because of the lack of tests) is too big. This however, doesn’t mean refactoring tools aren’t useful in this scenario. On the contrary; they help a lot.
If you haven't already, I'd advise you to read Michael Feathers' book Working Effectively with Legacy Code. It describes in great details a series of patterns that help you refactor legacy code to a more testable system.
Good luck.
When it comes to static call dependencies, you might want to check out Moles. It's able to do code injection at run-time to stub out any static or non-virtual method call with your own test implementation. This is handy for testing legacy code that wasn't designed using testable dependency-injected interfaces.

Modify an internal .NET class' method implementation

I would like to modify the way my C#/.NET application works internally. I have dug into the .NET framework with Reflector and found a pretty good place where I could use a different implementation of a method. This is an internal class in the System.Windows.Forms namespace. You obviously cannot alter the code of this class with the usual means so I thought it would be possible to replace a method in there through reflection at runtime. The method I would like to entirely replace for my application is this:
public static WindowsFontQuality WindowsFontQualityFromTextRenderingHint(Graphics g)
in the class:
internal sealed class System.Windows.Forms.Internal.WindowsFont
Is there any way to load that type and replace the method at runtime, not affecting any other applications that are currently running or started afterwards? I have tried to load the type with Type.GetType() and similar things but failed so far.
You may be able to do this with the debugger API - but it's a really, really bad idea.
For one thing, running with the debugger hooks installed may well be slower - but more importantly, tampering with the framework code could easily lead to unexpected behaviour. Do you know exactly how this method is used, in all possible scenarios, even within your own app?
It would also quite possibly have undesirable legal consequences, although you should consult a lawyer about that.
I would personally abandon this line of thinking and try to work out a different way to accomplish whatever it is you're trying to do.
Anything you do to make this happen would be an unsupported, unreliable hack that could break with any .NET Framework update
There's another, more correct, way to do what you are trying to accomplish (and I don't need to know what you're trying to do to know this for certain).
Edit: If editing core Framework code is your interest, feel free to experiment with Mono, but don't expect to redistribute your modifications if they are application-specific. :)
I realy think, this is not good idea. But if you realy need it, you can use a Mono Cecil and change the assembly content. Then you need setup a config file for Redirecting Assembly Versions.
And last but not least, your advance will be propable illegal.

Categories

Resources