SpecFlow: how to inject ScenarioContext when NInject is used as IoC - c#

After updating our solution from SpecFlow1.9 to 2.0 and NUnit2.6.4 to 3.2.1 we get a SpecFlowException when the SpecFlow tests are executed with NCrunch
TechTalk.SpecFlow.SpecFlowException : The ScenarioContext.Current static accessor cannot
be used in multi-threaded execution. Try injecting the scenario context to the binding
class. See http://go.specflow.org/doc-multithreaded for details.
at TechTalk.SpecFlow.ScenarioContext.get_Current()
The solution the link http://go.specflow.org/doc-multithreaded in the exception text suggests only works when you use the build-in mini IoC of SpecFlow. However, we use NInject as IoC in our SpecFlow tests. Just wrapping the static field ScenarionContext.Current in a class and registering that class in a singleton context of course just moves the problem to another place.
Does anybody knows how to inject the ScenarionContext when NInject is used instead of the build-in IoC of SpecFlow?

SpecFlow now supports other containers via plugins for each container. Only one container can be used as it is injected into SpecFlows container. So if you use the Ninject plugin, then you can only use the Ninject plugin.
Unfortunately the developer who created the Ninject plugin did not publish it to NuGet so you'll have to build it yourself.
https://github.com/MattMcKinney/SpecFlow.Ninject
And you might want to ask him which license his plugin is using.

Related

Dependency Injection calls in Libraries .NET Core

What is the correct way for a Libary to call an object that was injected through Dependency Inject?
Background: I have multiple .NET Core app that uses dependency injection for all major objects and uses libraries for reusability. It is working great. App1 calls Libary1 and Libary2. App2 calls Libary2 and Libary3 etc.
service.AddTransient<Libary1.ILibary1Dependency, Libary1.Libary1Dependency>();
service.AddTransient<Libary2.ILibary1Dependency, Libary2.Libary1Dependency>();
service.AddTransient<Libary2.ILibary2Dependency, Libary2.Libary2Dependency>();
service.AddTransient<Libary3.ILibary1Dependency, Libary3.Libary1Dependency>();
Now in Libary2.ILibary1Dependency there is a method that needs to call a new Libary2.ILibary2Dependency. What is the best way to do this?
Should I just do a new Libary2.ILibary2Dependency(property1, property2...);?
Is it ok in the main app to actually inject the IServiceCollection object and then in the constructor of the Libary2.ILibary1Dependency get the IServiceCollection?
Is there some nugget package that I don't know about that fixes this perfectly?
Note: Libary2.ILibary2Dependency does get called on its own via dependency injection, if you were wondering
As suggested in the comments, keep the libraries independent of the Service Dependency Injection. And let the Caller make the decision to inject them on need basis and it helps to keep the libraries independent of IOC Framework.
If you need to change the IOC Framework or even upgrade to latest versions, you probably need to spend time to update across the libraries, the more these dependencies you have the more house cleaning needed eventually.
I have seen people creating generic wrappers to avoid having specific dependencies on IOC Frameworks, but its kind of overkill.
If all you have is a 3 or 4 projects, it doesn't matter to refactor them away in both directions.

SetResolver in console application using Simple Injector

I am looking to do the equivalent of this:
DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));
But in a console application. I also have cases where I need to do this in a worker role. I don't want to have to add a reference to the MVC dll all over the place. I am wondering if there is an equivalent for non-mvc projects? I need to stash the container I create so I can access it throughout my application. I thought of creating a static variable, but I'd rather not do this.
I saw there is a CommonSerivceLocator nuget for Simple Injector but oddly it requires 2.8.1 and the latest non-mvc Simple Injector is 2.8.0.
I don't want to have to add a reference to the MVC dll all over the place.
This indicates that you are not applying dependency injection but are doing Service Location, which is an anti-pattern.
If you apply constructor injection to all your components, you will be able to let Simple Injector build up a complete object graph of dependent components (of many levels deep) without any of your components to know about the existence of an IoC container such as Simple Injector or an IoC abstraction such as the Common Service Locator and MVC's IDependencyResolver. This prevents you from referencing your IoC container or such abstraction "all over the place".
So in a Console Application that means that you typically have one place where you resolve the object graph(s). This is the place in the application that already knows about the existence of the IoC container. This place is typically referred to as the Composition Root.
I saw there is a CommonSerivceLocator nuget for Simple Injector but oddly it requires 2.8.1 and the latest non-mvc Simple Injector is 2.8.0.
I seem to have made an error in the build scripts that create the NuGet packages and although NuGet usually applies checks when a package is uploaded, for some reason it failed to check this. I fixed this and pushed v2.8.2 of the CommonServiceLocator adapter to NuGet. But note that we are dropping support for the CSL adapter in v3 of Simple Injector because it leads to bad practice. Don't use it; you don't need it.

Is there a better option than the Singleton pattern for exposing my classes' dependencies, if I'm not using an IoC container?

I am building a class library to be consumed by other applications. I do not have an IoC container as I do not wish to force it on the consumers of my library.
Consumers should be able to configure the library in their bootstrapper, as per this example:
Example.Configure({ x =>
{
x.AddSomeSetting();
x.AddAnotherSetting();
});
Any future use of the library should use this central configuration:
// exampleObject should use the central configuration defined above
var exampleObject = new Example.SomeClass();
I have used a singleton class to store the configuration, which is accessed by the rest of the library in future.
The problem comes when unit testing. As soon as a unit test method modifies the singleton configuration, all of the other unit tests are affected by this modification.
I could have a Reset() method on the singleton that is called at the start of each test, but it would be there purely for the test.
Is there a better solution than storing this global state as a singleton?
Simple: provide an instance of the configuration to each library component in its constructor. That might be a little more verbose than you want, but it meets your design goal and it gives the library user complete freedom (maybe even to use a dependency injection library themselves).

How do I inject MEF [ImportingConstructor] dependencies registered with Windsor?

I'm working on a C#/MVC app that currently uses Windsor as a DI framework, and have just started exploring MEF to make the app more extensible. It's been working beautifully, right up till the point where my plugins need to have dependencies satisfied.
How can I inject Windsor managed dependencies into a class that is imported by MEF, preferably with [ImportingConstructor]?
I've tried extending ContainerAdapterBase from MefContrib but can't figure out how to get it to work with [ImportingConstructor]. Also, using MEF for IoC is not an option.
Thanks!
Update:
My current solution is to write a simple 'DSL', managed by Windsor, that provides all the functionality required by plug-ins, and then manually inject that whenever MEF passes me a plug-in instance. Possibly a bit nasty but it works, it also means I don't have to do any service location from plugins, and also provides a nice boundary around what a plugin is 'allowed' to do.
Any thoughts on this approach would be greatly appreciated.

IOC in Winforms plugin architecture

I am working with an architecture that has a main program. When this starts it looks in the executing path via reflection for DLL's that have inherited off a base class. These are the plugins.
When a new requirement for a new project arises typically a new plugin is created. This plugin has the main plugin class and then possibly a number of other classes and windows forms.
The main plugin class has initialize methods but as its a class library there is no program.cs so to speak to wire up dependencies.
Is there a way via an app.config to wire up dependencies or do you think I should avoid using an IOC Container and just have a factory method in the plugin class that wires up the dependencies some how?
The issue is I may not have the ability to change the main application's code to setup the IOC container
All major IoC containers have the ability to wire up dependencies with app.config or via an assembly discovery mechanism (like you describe). Typically the main application sets up the container, and then defers to the container to find the plugins (which may be configured via configuration or by assembly probing like you describe above).
For SpringFramework.net, as an example of app.config: http://www.springframework.net/doc-latest/reference/html/objects.html#d4e437
For Castle Windsor, an example of assembly probing: http://stw.castleproject.org/Windsor.Installers.ashx
Whilst I think your question is a bit vague, based on what I gather from your question I would have to say IoC would most likely be the best way to go! You can use your IoC container to wire up the factories if you like, or you can use it to wire up the PlugIn dependencies, Personally, I like to use StructureMap. A very versatile and easy to use IoC container.
You could use the app.config to list the dependancy names and then feed the IoC the names to create dependencies. Use something like Activator to then create instances. Personally, I would use both IoC and factories. I would use the app.config to specify the dependency names and then use a Factory to dish out the instances of the plugIn classes. And finally I would then use the IoC container to specify the implementation of the factory(ies).
Hope that is of some use!

Categories

Resources