I have a mapper that takes data from a repository project. I have a IMenueMapper interface that is passed into the homecontroller like this:
public HomeController(IMenueMapper menueMapper)
{
_menueMapper = menueMapper;
}
but the menuemapper class itself use the IMenueMapperRepository, and this come from another project and is passed in via dll
public MenueMapper(IMenueItemsRepository menueItems)
{
_menueItems = menueItems;
}
While I can easily resolve the IMenuemapper in the MVC project, using structuremap.mvc5, I can't resolve the repository. Is there a way of achieving the DI in this instance?
You need to register the abstraction (repository interface and implementation) in the composition root.
You indicated that the IMenueMapper is registered via;
scan.AssemblyContainingType<MenueMapper>();
Since
but the MenueMapper class itself use the IMenueMapperRepository, and
this come from another project and is passed in via dll
Then it should also be scanned as it belongs to another assembly
scan.AssemblyContainingType<MenueItemsRepository>();
Make sure that the project references the assembly in question
Related
From what I understand, in abp, when a class implements, ITransient interface, it is automatically registered in the dependency injection system.
When I create a new project in ASPNetZero, and a class implements the ITransient, I cannot inject the said class in other projects e.g Application
Using the following snippet does not allow me to use constructor injection.
public interface ITrackAppService : ITransientDependency
public class TrackAppService : ITrackAppService
But when I register it (Even if the class does not implements ITransient), then I can use constructor injection.
IocManager.RegisterIfNot<ITrack, Track>();
Did I mistakenly understood how ITransient works?
How do I use Itransient so I can use constructor dependency injection?
Note: The class I'm trying to inject to the Application project is in a different project I created.
If you are injecting an interface to a new project, you cannot use it that way out of the box. Because your new project doesn't know your dependencies.
Each new project that uses DI must to be set as an AbpModule.
See a sample module declaration.
[DependsOn(typeof(MyBlogCoreModule))]
public class MyBlogApplicationModule : AbpModule
{
public override void Initialize()
{
IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly());
}
}
Look out the [DependsOn] attribute on the class. This helps to register the project to the DI.
So what you need to do is,
Create a new class in the new project like I showed you above.
Add the [DependsOn(typeof(YourApplicationServiceModule))] attribute to this new module.
I have a WPF application for which my users can create their own plugins by using MEF. Each plugin implements an interface that allows the main application to perform CRUD operations on some data source, e.g. a database.
I have created 2 plugins:
LocalDatabase - provides data from an SQLite database
RemoteDatabase - provides data from a MySQL database
Both are using Entity Framework to do their job. Each of those plugins needs to have its own implementation of the DbConfiguration class.
Now, the problem is that the WPF application loads those 2 plugins, but fails to assign each of them their own implementation of the DbConfiguration class, because it seems that you can have only one DbConfiguration per AppDomain.
So I always have only one of those plugins working.
I was thinking about having just one implementation of the DbConfiguration class and give each plugin an option to add its required configs to that, but the problem is that it creates some coupling between the WPF application and Entity Framework. I'd like to keep the Entity Framework stuff only inside the plugins without the need of modifying the WPF application. It shouldn't care about what plugins use to access their data source.
Is there any way of making it work this way? Could I maybe somehow create a separate AppDomain per each plugin, so maybe then each could use its own DbConfiguration class?
I've found a solution which is a bit hacky, but it does seem to work, so I thought I'd post it, in an unlikely case that someone would face the same issue somewhere in the future.
After some additional research, I've learnt that you can use the DbConfiguration.Loaded event to register some additional Dependency Resolvers for EF. So, in each plugin's constructor, I subscribe the event and add a new Dependency Resolver: SQLite for the LocalDatabase and MySql for the RemoteDatabase. I got rid of the custom DbConfiguration classes from each plugin.
This looked promising, but actually a new problem appeared - there were cases where LocalDatabase plugin called the MySql resolver and it actually returned the MySql implementation of the requested service type. Obviously the LocalDatabase plugin couldn't work with that, because it expected the SQLite implementation. And vice-versa.
So, each of the Resolvers, would actually need to check who called the GetService method - if it's some method from the same assembly that the custom resolver is in, it tries to resolve. Otherwise it's assumed that a resolver from different plugin should take care of that request and it returns null to actually let it do that.
The problem is that the GetService method doesn't supply any information about the requester. So that's where I came up with the hacky solution, which uses StackTrace to check whether any of the called methods belongs to the same Assembly that the current Resolver resides in.
public class CustomMySqlDbDependencyResolver : IDbDependencyResolver
{
private readonly Assembly _executingAssembly = Assembly.GetExecutingAssembly();
private readonly MySqlDependencyResolver _mySqlResolver = new MySqlDependencyResolver();
public object GetService(Type type, object key)
{
var stackTrace = new StackTrace();
StackFrame[] stackFrames = stackTrace.GetFrames().Skip(1).ToArray();
bool shouldResolve = stackFrames.Any(f => f.GetMethod().DeclaringType.Assembly.Equals(_executingAssembly));
if (!shouldResolve)
{
return null;
}
var resolvedService = _mySqlResolver.GetService(type, key);
return resolvedService;
}
public IEnumerable<object> GetServices(Type type, object key)
{
var service = GetService(type, key);
if (service != null)
{
yield return service;
}
}
}
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.
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.
I have layered asp.net MVC application. My application has following architecture:
DomainLayer, which contains domain objects
DAL (repository pattern), has reference only to DomainLayer
BLL, has reference to DomainLayer and DAL
PresentationLayer(Web), has reference to DamainLayer and BLL
And I have separate layer(let's call it DependencyResolver), which is responsible for resolving dependencies through all application layers. I use Ninject dependency resolver. This project has references to DomainLayer, DAL and BLL
I need to resolve dependencies of some object in different ways based on logged user role. For example I have 2 implementations of the same IOrderRepository: OrderSQLRepository and OrderMemoryRepository:
For UserRole.Admin I have to call
Bind<IOrderRepository>().To<OrderSQLRepository>();
And for other users I need to bind interface to IOrderMemoryRepository which accepts the Session as constructor argument, to store values temporary in session.
Bind<IOrderRepository>().To<OrderMemoryRepository>().WithConstructorArgument("pSession", HttpContext.Current.Session);
So as there is conditional case, I use ToProvider method:
Bind<IOrderRepository>().ToProvider<OrderRepositoryProvider>();
public class OrderRepositoryProvider : IProvider
{
public Type Type { get { return typeof(IOrderRepository); } }
public object Create(IContext context)
{
if (HttpContext.Current.User.IsInRole("Admin"))
{
return context.Kernel.Get<OrderMemoryRepository>(new ConstructorArgument("pSession", HttpContext.Current.Session["Orders"]));
}
return context.Kernel.Get<OrderSQLRepository>();
}
}
But as the bindings are perforemed in separate project, which does not have reference to System.Web.Mvc namespace, I couldn't use HttpContext.Current.
So what would you suggest, am I in right direction or should I use different approach or if the direction is right, how can I pass the HttpContext.Current to Load() method of NinjectModule or to OrderRepositoryProvider
You are on the right track, however, typically in a web application the web layer is the composition root (contains all your bindings) because it is the entry point into the app. in other words, put all your bindings into the web layer as NinjectModules.
Additionally, you may consider creating wrappers for the HttpContext values you want to use. for example, IHttpContext that implements a getter for HttpContext.Current.User and then use the interface in your provider instead of the concrete HttpContext.Current. I would do the same for retrieving the orders from session, i.e., ISessionOrders and then Ninject would be able to resolve the dependency for OrderMemoryRepository without a constructor argument.
so then you would have:
public object Create(IContext context)
{
if (context.Kernel.Get<IHttpContext>().User.IsInRole("Admin"))
{
return context.Kernel.Get<OrderMemoryRepository>();
}
return context.Kernel.Get<OrderSQLRepository>();
}