Who instantiates the test class in a test class project? - c#

I am writing some integration tests. I am using Dependency Injection with Windsor Castle.
I would like to resolve the test class using an inversion of control container. I do not think that resolve all my dependencies inside the test class is the solution for my case.
I would like to do what I have done inside the web api project. I implemented IHttpControllerActivator, which is an extension point to fully control controller's life-cycle. That is, we can define how a controller is instantiated.
I would like to do the same for the tests. But I do not understand which is the interface I have to implement. Can anyone help me?
I think I just need to know which is the corresponding IHttpControllerActivator for unit test.
EDIT
I have a web api project to test. The web api project resolves all the dependencies with WindsorCastle. Now I need to test the web api. This is what I am doing:
public voi MyTest_Ok()
{
//Arrange
var myController = new MyWebApiController();
var result = await myController.DoWork();
//Asserts
}
Obviously it does not work because I am not using castle windsor to resolve the controller and so I do not resolve any dependency from web api controller to bottom.
I think I could replace this line
var myController = new MyWebApiController();
with something like this
var myController = windsorContainer.Resolve<MyWebApiController>();
But this solution I think is wrong. I think it's better to resolve dependencies as happen inside the controller:
public class MyWebApiController : ApiController()
{
public InjectedDependency dep { get; set; }
public DoWork()
{
dep.DoWork();
}
}
I can do this because I have implemented a custom IHttpControllerActivator.

Answer is: your test framework does. As I know none of the common test frameworks allows you take control over creating your test classes.
More info about this here as well:
A .NET Unit Test without a parameterless constructor, to facilitate dependency injection
NUnit provide ParameterizedTestFixture -https://github.com/nunit/docs/wiki/TestFixtureData
So in theory as a dirty workaround you would be able to inject some dependencies trough constructor by this, but it wasn't designed for this purpose.
In general you have to go for service locator.

Related

How do I get access to INodeServices without dependency injection

I'd like to run some node code from my c#. Microsoft.AspNetCore.NodeServices seems to be the way to do this job however the examples are all very similar and all involve putting
services.AddNodeServices();
in the configure services function and then DI adds the implementation of INodeServices to a controller. Like this
public class foo
{
private readonly INodeServices _nodeServices;
public foo(INodeServices nodeServices)
{
_nodeServices = nodeServices;
}
}
As I'm using this in a class library rather than a webapi how is DI going to work? Also how do I call the class from a unit test, what can I pass into the constructor? I'm sure I'm missing something obvious.
The concept of DI is that it can be used to resolve object graphs. That is, it doesn't just resolve dependencies of the Controller class, but dependencies of those dependencies, dependencies of those dependencies, etc.
To use INodeServices in your own library, you simply need to reference Microsoft.AspNetCore.NodeServices, then accept it as a constructor parameter.
public class MyServiceFromMyLibrary : IMyServiceFromMyLibrary
{
private readonly INodeServices nodeServices;
public MyServiceFromMyLibrary(INodeServices nodeServices)
{
this.nodeServices = nodeServices;
}
// ...
}
Then reference your library from the Web API project and inject your service into a controller.
public class FooController
{
private readonly IMyServiceFromMyLibrary myService;
public FooController(IMyServiceFromMyLibrary myService)
{
this.myService = myService;
}
}
DI takes care of putting the INodeServices instance into your class provided it is registered in your composition root, as follows.
services.AddNodeServices();
services.AddTransient<IMyServiceFromMyLibrary, MyServiceFromMyLibrary>();
If your end game is to create a reusable library rather than an application layer refer to DI Friendly Library for some techniques to make your library easier to use without the use of dependency injection.
Also how do I call the class from a unit test, what can I pass into the constructor?
For a unit test, you would just need to mock INodeServices. The simplest way is to use a mocking library, such as Moq.
var mock = new Mock<INodeServices>();
mock.Setup(ns => ns.InvokeAsync(It.IsAny<string>())).Returns(...);
var target = new MyServiceFromMyLibrary(mock.Object);
// .. Call a method on target and then assert the results
References:
Using Node Services in ASP.NET Core
Dependency injection in ASP.NET Core

Where dependency-injection registrations have to be put?

I've read the question Ioc/DI - Why do I have to reference all layers/assemblies in application's entry point?
So, in a Asp.Net MVC5 solution, the composition root is in the MVC5 project (and having a DependencyInjection assembly in charge of all the registrations does not make sense).
Within this picture, it is not clear to me what is the better approach among the following.
Approach 1
The concrete implementations are public class ... and all registrations clauses are centralized within the composition root (e.g. in one or more files under a CompositionRoot folder). MVC5 project must reference all the assemblies providing at least one concrete implementation to be bound. No library references the DI library. MVC project can contain interfaces to be bound with no drawbacks.
Approach 2
The concrete implementations are internal class .... Each library exposes a DI 'local' configuration handler. For example
public class DependencyInjectionConfig {
public static void Configure(Container container) {
//here registration of assembly-provided implementations
//...
}
}
which is up to register its own implementations. The composition root triggers registrations by calling all the Configure() methods, just one for each project. MVC5 project must then reference all the assemblies providing at least one concrete implementation to be bound. Libraries must reference the DI library. In this case, the MVC5 project cannot contain interfaces (otherwise there would be a circular reference): a ServiceLayer assembly would be needed to hold public interfaces to be bound.
Approach 3
Same as Approach 2, but local configuration modules are discovered dynamically through assembly reflection (by convention?). So MVC5 project has not to reference libraries. MVC project can contain interfaces and can be referenced by libraries. Libraries must reference the DI library.
What is the best practice here? Is there some other better possibility?
EDIT 1 (2016-12-22)
Thanks to received answers, I published this github project describing the best solution I found so far.
EDIT 2 (2018-09-09)
This answer provides an interesting option.
EDIT 3 (2020-12-29)
Finally, I came up with a complete solution, packaged in the form of a WebApi application template. I published this solution on GitHub HERE. This approach, not only gives a clear understanding about where DI rules have to be put, but also suggests to setup the application according to SOLID principles and CQRS pattern. The commit history of this project has been structured to have educational purposes.
EDIT 4 (2023-01-31)
The repository linked above publishes an article describing the solution as well.
I typically like to encapsulate these types of things into each project. So for example I might have the following. (This is an extremely simplified example, and I'll use the AutoFac in this example, but I'd imagine all DI frameworks have something like the following).
Common area for just POCOs and Interfaces.
// MyProject.Data.csproj
namespace MyProject.Data
{
public Interface IPersonRepository
{
Person Get();
}
public class Person
{
}
}
Implementation of Repositories and Data Access
// MyProject.Data.EF.csproj
// This project uses EF to implement that data
namespace MyProject.Data.EF
{
// internal, because I don't want anyone to actually create this class
internal class PersonRepository : IPersonRepository
{
Person Get()
{ // implementation }
}
public class Registration : Autofac.Module
{
protected override void Load(ContainerBuilder builder)
{
builder.Register<PersonRepository>()
.As<IPersonRepository>()
.IntancePerLifetimeScope();
}
}
}
Consumer
// MyPrject.Web.UI.csproj
// This project requires an IPersonRepository
namespace MyProject.Web.UI
{
// Asp.Net MVC Example
internal class IoCConfig
{
public static void Start()
{
var builder = new ContainerBuilder();
var assemblies = BuildManager.GetReferencedAssemblies()
.Cast<Assembly>();
builder.RegisterAssemblyModules(assemblies);
}
}
}
So the Dependencies look like:
MyProject.Data.csproj
- None
MyProject.Data.EF.csproj
- MyProject.Data
MyProject.Web.UI.csproj
- MyProject.Data
- MyProject.Data.EF
In this setup, the Web.UI cannot know anything about what is registered nor for what reason. It only knows that the EF project has implementations but can't access them.
I can drop EF for say Dapper extremely easily as each project encapsulates it's own implementations and registration.
If I was adding unit tests and had an InMemoryPersonRepository, how would I swap out the PersonRepository for my InMemoryPersonRepository?
Assuming we ignore any business logic layer and have an MVC Controller directly access our Data Accessor, my code might look like:
public class MyController
{
private readonly IPersonRepository _repo;
public MyController(IPersonRepository repo)
{
_repo = repo;
}
public IActionResult Index()
{
var person = _repo.Get();
var model = Map<PersonVM>(person);
return View(model);
}
}
Then a test using nSubstitute Might look like:
public class MyControllerTests
{
public void Index_Executed_ReturnsObjectWithSameId
{
// Assign
var repo = Substitute.For<IPersonRepository>();
var expectedId = 1;
repo.Get().Returns(new Person { Id = expected });
var controller = new MyController(repo);
// Act
var result = controller.Index() as ActionResult<PersonVM>;
// Assert
Assert.That(expectedId, Is.EqualTo(result.Value.Id));
}
You've identified a real problem. (One could say it's a good problem to have.) If entry application Areferences B, B references C, and B and/or C require some DI registration, that makes A (your entry application) responsible for knowing enough about the details of B and C to register all the dependencies.
The solution is to have a separate assembly that handles composing all of the registrations for B and C. A references that, and it provides all of the container configuration that A needs to use B and C.
The benefits are
A doesn't know more about B and C than it should
Neither A, B, nor C have to be tied to one particular DI framework like Unity or Windsor.
Here's an example. This is an event bus class that works best with a DI container. But in order to use it you shouldn't have to know all about the dependencies it needs to register. So for Windsor I created a DomainEventFacility. You just call
_container.AddFacility<DomainEventFacility>();
and all of the dependencies are registered. The only thing you register are your event handlers.
Then if I want to use the same event bus library with a different DI container like Unity I can just create some similar assembly to handle the same configuration for Unity.

Castle Windsor IoC Property Injection simple how-to

OK I think there is maybe too much information about Castle Windsor because looking for these keywords gives me examples of everything, and frankly I don't understand enough about how it works to properly troubleshoot this. I have tried quite a few permutations with little luck at this point.
I have an IUnitOfWorkFactory that I want to instantiate as a singleton. So, I install Castle Windsor, write a bit of code like so:
iocContainer = new WindsorContainer()
.Install(FromAssembly.This());
var propInjector = iocContainer.Register(
Component.For<IUnitOfWorkFactory>()
.LifestyleSingleton()
.Instance(new NHUnitOfWorkFactory())
);
propInjector.Resolve<IUnitOfWorkFactory>();
This gets called from my Application_Start method.
I have an AccountController wired up like so:
public class AccountController : SecureController
{
public IUnitOfWorkFactory UnitOfWorkFactory { get; set; }
...
...as far as I can figure, this should just "work" (although don't ask me how). But my property is always null when I try to use it.
It seems like I'm missing something silly and simple, but I have no idea what it is.
I have also tried
var propInjector = iocContainer.Register(
Component.For<IUnitOfWorkFactory>()
.ImplementedBy<NHUnitOfWorkFactory>()
.LifestyleSingleton()
);
with no success.
What am I doing wrong?
CONCLUSION
I was missing several steps here. I had built an installer and a bootstrapper per the tutorial, but I registered my services at the wrong spot... before building the controller factory. Now my bootstrapper looks like this:
iocContainer = new WindsorContainer()
.Install(FromAssembly.This());
var controllerFactory = new WindsorControllerFactory(iocContainer.Kernel);
ControllerBuilder.Current.SetControllerFactory(controllerFactory);
iocContainer.Register(
Component.For<IUnitOfWorkFactory>()
.ImplementedBy<NHUnitOfWorkFactory>()
.LifestyleSingleton()
);
... and my property injections were no longer null.... now I just have to debug the other 87 problems...
Both constructor and property injection work when the root object is resolved by the container. In this case, your AccountController would be the root object that Windsor would need to create.
In order to wire this up, you should use a controller factory. Once the controller is registered and resolved by the container, everything should work as you expect.

Proper use of [Import] attribute in MEF

I'm learning MEF and I wanted to create a simple example (application) to see how it works in action. Thus I thought of a simple translator. I created a solution with four projects (DLL files):
Contracts
Web
BingTranslator
GoogleTranslator
Contracts contains the ITranslate interface. As the name applies, it would only contain contracts (interfaces), thus exporters and importers can use it.
public interface ITranslator
{
string Translate(string text);
}
BingTranslator and GoogleTranslator are both exporters of this contract. They both implement this contract and provide (export) different translation services (one from Bing, another from Google).
[Export(typeof(ITranslator))]
public class GoogleTranslator: ITranslator
{
public string Translate(string text)
{
// Here, I would connect to Google translate and do the work.
return "Translated by Google Translator";
}
}
and the BingTranslator is:
[Export(typeof(ITranslator))]
public class BingTranslator : ITranslator
{
public string Translate(string text)
{
return "Translated by Bing";
}
}
Now, in my Web project, I simply want to get the text from the user, translate it with one of those translators (Bing and Google), and return the result back to the user. Thus in my Web application, I'm dependent upon a translator. Therefore, I've created a controller this way:
public class GeneralController : Controller
{
[Import]
public ITranslator Translator { get; set; }
public JsonResult Translate(string text)
{
return Json(new
{
source = text,
translation = Translator.Translate(text)
});
}
}
and the last piece of the puzzle should be to glue these components (parts) together (to compose the overall song from smaller pieces). So, in Application_Start of the Web project, I have:
var parts = new AggregateCatalog
(
new DirectoryCatalog(Server.MapPath("/parts")),
new DirectoryCatalog(Server.MapPath("/bin"))
);
var composer = new CompositionContainer(parts);
composer.ComposeParts();
in which /parts is the folder where I drop GoogleTranslator.dll and BingTranslator.dll files (exporters are located in these files), and in the /bin folder
I simply have my Web.dll file which contains importer. However, my problem is that, MEF doesn't populate Translator property of the GeneralController with the required translator. I read almost every question related to MEF on this site, but I couldn't figure out what's wrong with my example. Can anyone please tell me what I've missed here?
OK what you need to do is (without prescribing for performance, this is just to see it working)
public class GeneralController : Controller
{
[Import]
public ITranslator Translator { get; set; }
public JsonResult Translate(string text)
{
var container = new CompositionContainer(
new DirectoryCatalog(Path.Combine(HttpRuntime.BinDirectory, "Plugins")));
CompositionBatch compositionBatch = new CompositionBatch();
compositionBatch.AddPart(this);
Container.Compose(compositionBatch);
return Json(new
{
source = text,
translation = Translator.Translate(text)
});
}
}
I am no expert in MEF, and to be frank for what I use it for, it does not do much for me since I only use it to load DLLs and then I have an entry point to dependency inject and from then on I use DI containers and not MEF.
MEF is imperative - as far as I have seen. In your case, you need to pro-actively compose what you need to be MEFed, i.e. your controller. So your controller factory need to compose your controller instance.
Since I rarely use MEFed components in my MVC app, I have a filter for those actions requiring MEF (instead of MEFing all my controllers in my controller facrory):
public class InitialisePluginsAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
CompositionBatch compositionBatch = new CompositionBatch();
compositionBatch.AddPart(filterContext.Controller);
UniversalCompositionContainer.Current.Container.Compose(
compositionBatch);
base.OnActionExecuting(filterContext);
}
}
Here UniversalCompositionContainer.Current.Container is a singleton container initialised with my directory catalogs.
My personal view on MEF
MEF, while not a DI framework, it does a lot of that. As such, there is a big overlap with DI and if you already use DI framework, they are bound to collide.
MEF is powerful in loading DLLs in runtime especially when you have WPF app where you might be loading/unloading plugins and expect everything else to work as it was, adding/removing features.
For a web app, this does not make a lot of sense, since you are really not supposed to drop a DLL in a working web application. Hence, its uses are very limited.
I am going to write a post on plugins in ASP.NET MVC and will update this post with a link.
MEF will only populate imports on the objects which it constructs itself. In the case of ASP.NET MVC, it is ASP.NET which creates the controller objects. It will not recognize the [Import] attribute, so that's why you see that the dependency is missing.
To make MEF construct the controllers, you have to do the following:
Mark the controller class itself with [Export].
Implement a IDependencyResolver implementation which wraps the MEF container. You can implement GetService by asking the MEF container for a matching export. You can generate a MEF contract string from the requested type with AttributedModelServices.GetContractName.
Register that resolver by calling DependencyResolver.SetResolver in Application_Start.
You probably also need to mark most of your exported parts with [PartCreationPolicy(CreationPolicy.NonShared)] to prevent the same instance from being reused in several requests concurrently. Any state kept in your MEF parts would be subject to race conditions otherwise.
edit: this blog post has a good example of the whole procedure.
edit2: there may be another problem. The MEF container will hold references to any IDisposable object it creates, so that it can dispose those objects when the container itself is disposed. However, this is not appropriate for objects with a "per request" lifetime! You will effectively have a memory leak for any services which implement IDisposable.
It is probably easier to just use an alternative like AutoFac, which has a NuGet package for ASP.NET MVC integration and which has support for per-request lifetimes.
As #Aliostad mentioned, you do need to have the composition initialise code running during/after controller creation for it to work - simply having it in the global.asax file will not work.
However, you will also need to use [ImportMany] instead of just [Import], since in your example you could be working with any number of ITranslator implementations from the binaries that you discover. The point being that if you have many ITranslator, but are importing them into a single instance, you will likely get an exception from MEF since it won't know which implementation you actually want.
So instead you use:
[ImportMany]
public IEnumerable<ITranslator> Translator { get; set; }
Quick example:
http://dotnetbyexample.blogspot.co.uk/2010/04/very-basic-mef-sample-using-importmany.html

IoC and ASP.NET MVC Controllers

Should I do something along the lines of this? I'm thinking of all my controllers inheriting from BaseController. Does this break the design pattern of IoC? What else should I do instead?
public class BaseController: Controller
{
protected ICookieService CookieService {
get {
return ServiceResolver.Resolve<ICookieService>(new { HttpContext = HttpContext });
}
}
protected IDateTimeService DateTimeService {
get {
return ServiceResolver.Resolve<IDateTimeService>();
}
}
protected ISettingsService SettingsService {
get {
return ServiceResolver.Resolve<ISettingsService>();
}
}
}
It would be a lot simpler to go with constructor injection and have a controllerfactory inject it for you. If you can, don't use a service locator (your ServiceResolver ) if you can get away with constructor injection.
There's some info on it on Adding a controller factory to ASP MVC
The link shows how to do it with StructureMap and it looks like you're using Unity, but it should be straightforward to adapt.
I'm assuming that the protected interfaces you have are dependencies for the controller. Its possible to set up an IoC container to inject the dependencies for you. It can certainly be done with Castle Windsor. You would need to change you BaseController class to have a constructor with the required dependencies, as long as the IoC container knows about the other services it'll be able to inject them.
One of the principles behind Inversion of Control and Component-Driven Development is about using static service locators only when there is no other way (i.e.: in web service hosts or object data sources).
Technically speaking, using static service locators the base controller does not violate IoC, it just does not use it.
Check out existing integration between Autofac IoC container and ASP.NET MVC (other containers should be able to do that as well).

Categories

Resources