I am trying dagger in one of my projects and i am experiencing this situation:
"Field injection only works if I declare the class as an entry point in the module definition."
Is this the correct behaviour?
The below dependencies are not injected to Messenger class if Messenger.class is not declared as an entry point. Constructor injector works fine but I don't want to declare a multi parameter constructor.
public class Messenger implements NetworkInterfaceListener {
#Inject public NetworkInterface networkInterface;
#Inject public MessageFactoryInterface messageFactory;
#Inject public Bus bus;
#Inject public Logger log;
...
...
}
You have only two alternatives: either to declare injectable constructor with all params to be injected or enlist class into entryPoints (now called injects) of your dagger module and call mGraph.inject(this) in default constructor (or whenever you need to actually "inject" maybe even outside the class).
Related
I am experiencing an issue, and I have come to a dead end on how to debug and resolve this.
I have an MVC application which is using Ninject for IoC and DI.
One of my dependencies is IApplicationLogger which I am currently implementing using Log4Net.
In my NinjectWebCommon I am binding my IApplicationLogger as follows:
kernel.Bind<IApplicationLogger>()
.ToMethod(ctx =>
{
string configFile = System.Configuration.ConfigurationManager.AppSettings["log4netconfigfilelocation"];
log4net.Config.XmlConfigurator.Configure(new System.IO.FileInfo(HttpContext.Current.Server.MapPath(configFile)));
var name = ctx.Request.Target.Member.DeclaringType.FullName;
var log4Netlogger = log4net.LogManager.GetLogger(name);
return new Log4NetApplicationLogger(log4Netlogger);
}).InTransientScope();
All fairly straight forward stuff.
However, I am finding that the first instance of IApplicationLogger which is activated is then passed to all constructors which require an IApplicationLogger instance.
for example I have the following
public class A : IA
{
public A(IB bclass, IC cclass, IApplicationLogger logger){}
}
public class B : IB
{
public B(IApplicationLogger logger){}
}
public class C : IC
{
public C(IApplicationLogger logger){}
}
I have set breakpoints on each constructor and also the line in my NinjectWebCommon kernel.Bind().ToMethod(ctx =>
What I see is this:
Break point in NinjectWebCommon is hit, and I can see
ctx.Request.Target.Member.DeclaringType.FullName is Class B.
Break point in Constructor Class B is hit and logger
instance is correct
Break point in Constructor Class C is hit, and
logger instance has a logger name of Type Class B
Break point in Constructor Class A is hit, and logger instance has a logger
name of Class B
I would expect the breakpoint within NinjectWebCommon to be hit for each new instance of IApplicationLogger that is required, but it is only hit once for the first activation for the instance of Class B.
I have tried my Binding without the InTransientScope() option.
My IA, IB and IC bindings are defined InSingletonScope(). This shouldn't cause an issue as I am expecting Ninject to activate an instance of each, each with it's own instance of IApplicationLogger.
The result of the binding I am seeing currently is that logging statements I output in say Class A are being recorded in the Log as being from a logger name for class of type B.
Can anyone suggest how I can diagnose why Ninject is reusing the TransientScoped() IApplicationLogger, or how I can peek under the hood of what Ninject is doing so that I can analyse this in greater detail?
For anyone interested I didn't discover the underlying issue here, but I have opted to inject an ILoggerFactory with a single method .GetLogger(string typename), allowing my classes to request their own Logger and passing their own Type name.
This way I can ensure that each Class has it's own logger, with the LoggerName matching the Class TypeName.
I've been using EntityFramework for a short time. Up until now I've only used the EF DBContext within discrete using blocks. I'm now trying to use request scope dependency injection. Unity seems to be the easiest, but I'm not sure if I'm using it correctly.
So far I've created a sample repository and service class (with corresponding interfaces). I register these in Unity, like so...
Public Shared Sub RegisterComponents()
Dim container = New UnityContainer()
container.RegisterType(Of IMyService, MyService)()
container.RegisterType(Of IRepository(Of MyModel), MyRepository)()
DependencyResolver.SetResolver(New UnityDependencyResolver(container))
End Sub
My repository looks like this...
Public Class MyRepository
Implements IRepository(Of EF.MyModel)
<Dependency>
Public Property Context() As MyDBEntities
Public Function Create(item As MyModel) As Boolean Implements IRepository(Of MyModel).Create
Context.MyModel.Add(item)
Return Context.SaveChanges() > 0
End Function
Public Function Delete(id As Integer) As Boolean Implements IRepository(Of MyModel).Delete
Context.MyModel.Remove([Get](id))
Return Context.SaveChanges() > 0
End Function
Public Function [Get](id As Integer) As MyModel Implements IRepository(Of MyModel).Get
Return Context.MyModel.Find(id)
End Function
Public Function List() As IQueryable(Of MyModel) Implements IRepository(Of MyModel).List
Return Context.MyModel
End Function
End Class
My service class includes the following reference to the repository...
<Dependency>
Public Property Repository() As IRepository(Of MyModel)
The rest of the service class at the moment is pretty much just a wrapper for the repository methods, but will eventually have more high-level functionality.
In my controller I reference my service like so...
<Dependency>
Public Property MyModelService() As IMyService
Anyway this all seems to work fine, I can add additional bits to the queries at repository, service, or controller level and it always seems to have the correct context. However I'm not sure how it will know to track and close the DBContext, as it's not explicitly registered with Unity.
Does it just figure this out itself because of the <Dependency> property decoration?
yes, unity is able to resolve the context implicitly.
However, when you register it explicitly you'll have more control over the lifetime, because you can tell Unity which lifetimemanager to use.
As implicit resolved types are created with the transient lifetimemanager
(see also: Unity: Change default lifetime manager for implicit registrations and/or disable them ) the lifetime of your context is the same as the lifetime of your repository.
for reference: https://msdn.microsoft.com/en-us/library/ff660872%28v=pandp.20%29.aspx
Short version: how to inject an object inside Action in Play Framework?
Long version: In my project I have custom annotation action #AuthenticationRequired which loads User object from the database and puts it into context.args. It uses DAO class that implements UserDAO. Now I want to use DAO class injected into Action by Google Guice. I can use Guice and inject instances in controllers and tests, but I have difficulties injecting DAO class inside Action.
Injector is a field on GlobalSettings instance.
I tried to override GlobalSettings#onRequest() and put UserDAO instance to context.args and then retrieve it from inside AuthenticationRequired action, but it turns out that Action returned by GlobalSettings#onRequest() being called last in the chain of action used with #With and/or custom annotations, so, it is to late.
I also tried to inject DAO instance by annotating action constructor, but but it uses no-args constructor to create an instance of action.
Any ideas how can I achieve this?
For play 2.5 you can simply add #Inject on top of the constructor of Action class and inject whatever needed. Here is a snippet from my working project (I'm using Guice as DI):
public class ChannelPermissionAction extends Action<ChannelPermission> {
private final AuthorizationService authorizationService;
private final AsyncHelper asyncHelper;
#Inject
public ChannelPermissionAction(AuthorizationService authorizationService, AsyncHelper asyncHelper) {
this.authorizationService = authorizationService;
this.asyncHelper = asyncHelper;
}
...
}
You can achieve this just the same as with controllers - describe your action as (a bean in my case - i'm using spring IoC) a dependency and get it called by
public <A> A getControllerInstance(Class<A> clazz)
of Application Global object. That's all you need - you'r dependencies would be injected.
BTW. Actions need to be created with each instance so in my case I should use "prototype" scope.
Mind it while using Guice - it should have similar functionality.
I get the following error from dagger:
[ERROR] error on execute: java.lang.IllegalArgumentException: Unexpected key: ca.nanometrics.apollo.instrument.configuration.ResourceOwnerController<>
I believe this happens because I have a class with no injectable dependencies - it has an empty public constructor (with #Inject), with nothing to inject in members either. I did this to not have to declare the #Provides for it. Note that the class with the #Inject is a subclass of the class listed in the error message above:
public class ResourceOwnerControllerHelios extends ResourceOwnerController<ResourceOwnerFactoryHelios>
{
#Inject
public ResourceOwnerControllerHelios()
{
// do nothing
}
Is this a bug in dagger, or is there something I am missing?
If I remove the #Inject and still don't add the #Provides to the module, it of course doesn't work at all, since dagger needs #Inject or #Provides on all dependencies.
Oi - this looks like its' bumping into a mishandling of generics. :/ Maybe file an issue on github. What you're doing should work - that is, adding #Inject to a no-args public constructor. I believe Dagger is trying to climb the inheritance hierarchy and not handling the generics in the parent. We should be handling this case.
i'm just starting out with asp.net mvc. It's a long way before you can really get to a live project. At the moment i'm working to build a blog using the asp.net mvc unleashed book.
However, i don't understand the 2 constructors in the BlogController (see question below)
Thx...
FIRST
The BlogController has a private variable '_repository'
Private _repository As BlogRepositoryBase
Public MustInherit Class BlogRepositoryBase
'blog entry methods
Public MustOverride Function ListBlogEntries() As List(Of BlogEntry)
Public MustOverride Sub CreateBlogEntry(ByVal BlogEntryToCreate As BlogEntry)
Public MustOverride Function QueryBlogEntries() As IQueryable(Of BlogEntry)
End Class
The BlogRepositoryBase gets inherited by EntityFrameworkBlogRepository _
The EntityFrameworkBlogRepository connects with BlogDBEntities
NEXT
The controller has 2 constructors 'new' and 'new with a parameter'
Public Sub New()
Me.New(New EntityFrameworkBlogRepository())
End Sub
Public Sub New(ByVal repository As BlogRepositoryBase)
_repository = repository
End Sub
QUESTIONS
What's going on with the constructors, i don't get that
How can a class of type 'EntityFrameworkBlogRepository' be passed to 'sub new' as BlogRepositoryBase? Isn't that another type?
The default constructor is calling the constructor with a parameter with a new instance of a particular type of BlogRepositoryBase class. EntityFrameworkBlogRepository must derive from this base class. The reason that you specify the base class (I would have used an interface, but I digress) is so in your tests you can specify a different type of repository -- one, perhaps, that doesn't even connect to a database by instantiating it directly via the non-default constructor. The framework wiil always use the default constructor, thus you have to both provide it and provide a suitable implementation of the repository using it.
FWIW -- this is how I would do it (in C# -- my brain isn't working well enough to translate into VB, yet).
protected IBlogRepository Repository { get; set; }
public BlogController() : this( null ) {}
public BlogController( IBlogRepository repository )
{
this.Repository = repository ?? new EntityFrameworkBlogRepository();
...
}
Tested as
public void Test()
{
var repository = MockRepository.GenerateMock<IBlogRepository>();
var controller = new BlogController( repository );
...
repository.VerifyAllExpectations();
}
EntityFrameworkBlogRepository is derived from BlogRepositoryBase
The 'magic' in the constructors is called Dependency Injection. (Wiki has more on that here.) In short, it is a way of making your code more maintainable and testable by passing it it's dependencies ... if you change the repository type you need not rip out most of your code.
Kindness,
Dan
Coding custom IControllerFactory or DefaultControllerFactory inherits class. And SetControllerFactory global.asax.
Haaked becomes reference very much.
TDD and Dependency Injection with ASP.NET MVC