Understanding dependency injection in a mvc controller - c#

The way dependency injection works is very mysterious to me. In this simple example:
public class LeagueController : BaseController
{
private readonly IDocumentSession documentSession;
public LeagueController(IDocumentSession documentSession) //where is this parameter coming from?
{
this.documentSession = documentSession;
}
What I don't get is where the initialized parameter is coming from to initialize this.documentSession? If I wanted to initialise another class in the constructor how would I do it?

Related

Null values passing on asp.net mvc 5 controller (Ninject DI)

I'm working on a MVC5 application and i'm trying to implement DI on my controller class. I have correctly put binding on Ninjectwebcommons. Still constructor of the controller class is receiving just null implementations.
public class AdServiceController : Controller
{
private IClientRequestPackage _clientReqPkg;
private ISearchAd _searchAd;
private ICreateConnection _createConnection;
private INewConnectionResult _newConnectionResult;
private IBuildDataObjects _buildDataObjects;
private IAdSearchResultObj _adSearchResultObj;
public AdServiceController (ICreateConnection createConnection)
{
_createConnection = createConnection;
}
This createConnection implementation has a dependency on Iconfigparams. I'm seeing Iconfigparams is just null.
Any help pl.
Chanu

Creating a DbContext with custom constructor with injected parameter in Entity Framework

I am working on a code first database, but when I try to do "Update-Database" I get the following error.
The target context 'AllMid.DL.Repository.Implementation.AllMidContext' is not constructible.
Add a default constructor or provide an implementation of IDbContextFactory.
Now it is apparent to me that the problem is that I don't have a default constructor or a an implementation of the IDbContextFactory interface, but in the sample project I am using I am seeing this done without either. Does anyone know how to go about this?
I currently have a DbContext resembling this.
internal class AllMidContext : DbContext, IAllMidContext
{
public DbSet<TreeEntity> Tree { get; set; }
public AllMidContext(IConfigurationAccess configAccess) : base(configAccess.GetDefaultConnectionString())
{
}
}
The configAccess should be being injected by structure map.
and a DataContextAccess class like this
internal class DataContextAccess : IDataContextAccess
{
private readonly IConfigurationAccess _configAccess;
public DataContextAccess(IConfigurationAccess configAccess)
{
_configAccess = configAccess;
}
public IAllMidContext GetAllMidContext()
{
return new AllMidContext(_configAccess);
}
}
Now the question is is there a way to do this without a default constructor or a factory? My dependency injection will always input the parameter so how can I get EF to use my custom constructor?
I believe that update-database is looking for a constructor with no input. what you can do is to write a constructor with no inputs and do your injection in its body.

How to use Singleton class injected by .NET MVC Ninject?

I have some problem with InSingletonScope().
My interface:
public interface ISettingsManager
{
ApplicationSettings Application { get; }
}
and my class:
public class SettingsManager : ISettingsManager
{
private readonly IConfigurationService _configurationService;
private readonly Lazy<ApplicationSettings> _applicationSettings;
public ApplicationSettings Application { get { return _applicationSettings.Value; } }
private SettingsManager(IConfigurationService context)
{
_configurationService = context;
_applicationSettings = new Lazy<ApplicationSettings>(() => new ApplicationSettings(context));
}
}
and binding looks like this:
kernel.Bind<ISettingsManager>().To<SettingsManager>().InSingletonScope();
What do you think about this approach?
For example, in HomeControler, when I'm add:
[Inject]
SettingsManager _settingsManager;
the _settingsManager is always null.
How I can use SettingsManager singleton in another project? I always get null.
What do you think about this approach?
InSingletonScope() - Only a single instance of the type will be created, and the same instance will be returned for each subsequent request. The dependency will have same scope as of Kernel i.e. Disposed when the Kernel is Disposed.
Read about object scopes here.
[Inject]
SettingsManager _settingsManager;
What are you trying to do here? Field injection?
I do not think it is supported. Copied following from official page:
Field Injection is a bad practice, and got cut for minimization as
part of the rewrite between v1 and v2. There is no field injection in
Ninject v2.
You can use Property or Constructor injection instead.
Property Injection:
[Inject]
public ISettingsManager SettingsManager { private get; set; }
Constructor Injection:
public class HomeController : Controller
{
readonly ISettingsManager settingsManager;
public HomeController(ISettingsManager settingsManager )
{
if(settingsManager == null)
throw new ArgumentNullException("settingsManager is null");
this.settingsManager = settingsManager;
}
}
You need to change your _settingsManager to have a type of ISettingsManager instead of SettingsManager.
(You're binding ISettingsManager to SettingsManager. This means when Ninject sees a dependency on ISettingsManager it will inject a SettingsManager. If something is directly declared as SettingsManager it won't do anything)

Accessing Ninject objects from master view partial view

I am trying to access an object created by ninject within my layout view but I have no idea how to access them.
Here is a brief outline of what I have tried so far:-
Created by service and bound them:
public interface IService
{
void SomeMethod();
}
public class Service : IService
{
public void SomeMethod
{
}
}
Bind<IService>().To<Service>();
Created a static class and use the [Inject] attribute:
public static class MasterLayout
{
[Inject]
public static IService Service { private get; set; }
public static void CallSomeMethod();
{
Service.SomeMethod
}
}
Everytime I call MasterLayout.CallSomeMethod() from my master view or partial view, the Service field is always null.
Is this even possible or should I be creating a base Controller and getting other controllers to inherit from it where I can set those values to be used within the master view and partial views? Is there an even better way of achieving this?
Does Ninject work if used with contructor injection?
( see http://ninject.codeplex.com/wikipage?title=Injection%20Patterns )
Something like
IUnitOfWork UnitOfWork;
public AccountController(IUnitOfWork unitOfWork)
{
this.UnitOfWork = unitOfWork;
}
Have you checked here?
bind to property always return null
When you say "on every page", you mean "on every controller"?
If yes, i think you could create a BaseController class, and all the controllers should inherit from it. I'm using this method.
You have to create a custom controller factory to have Ninject create the controllers. Once you do, this will work. There is also probably an extension for this already.

Database injection into a validation attribute with ASP MVC and Castle Windsor

I need some help - I am trying to use a custom validation attribute in an ASP.NET MVC web project that needs to make a database call.
I have windsor successfully working for the controllers and the IRepository interface is injected normally. The problem arrises when I need to inject the repository into the attribute class.
The attribute class has the following code:
public class ValidateUniqueUrlNodeAttribute : AbstractValidationAttribute
{
private readonly string message;
private readonly IArticleRepository articleRepository;
public ValidateUniqueUrlNodeAttribute(string message)
{
this.message = message;
}
public ValidateUniqueUrlNodeAttribute(string message, IArticleRepository articleRepository):this(message)
{
this.articleRepository = articleRepository;
}
public override IValidator Build()
{
var validator = new UniqueUrlNodeValidator(articleRepository) { ErrorMessage = message };
ConfigureValidatorMessage(validator);
return validator;
}
My problem is that I cannot seem to make Windsor intercept the contruction of the attribute to pass in the IArticleRepository
The current code in my global.asax file is as follows:
container = new WindsorContainer();
ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory(Container));
container
.RegisterControllers(Assembly.GetExecutingAssembly())
.AddComponent<IArticleRepository, ArticleRepository>()
.AddComponent<ValidateUniqueUrlNodeAttribute>();
Any help would be greatly appreciated.
AFAIK no dependency injection container can directly manage an attribute, since it's instantiated by the runtime and there's no way to intercept that.
However, they can cheat by either:
Using a static gateway to the container (example), or
Using a "BuildUp" feature that injects whatever dependencies are found within an already-constructed object. This is called BuildUp in Unity or InjectProperties in Autofac.
Windsor doesn't support #2 (ref1, ref2), so you can either:
Try one of the hacks to make Windsor support #2 (hack1, hack2)
Use a static gateway
Implement your own IValidatorBuilder and make it use Windsor to create validators. I'm sure this is implemented somewhere but I can't find it right now...
Don't know if this helps, but I subclassed ValidationAttribute to expose a Resolve<T>() method like so:
public abstract class IocValidationAttribute : ValidationAttribute
{
protected T Resolve<T>()
{
return IocHelper.Container().Resolve<T>();
}
}
Then it can be used in any custom ValidatorAttribute that needs to hit a database:
public class UniqueEmailAttribute : IocValidationAttribute
{
public override bool IsValid(object value)
{
ICustomerRepository customerRepository = Resolve<ICustomerRepository>();
return customerRepository.FindByEmail(value.ToString()) == null;
}
}
I think it's a variation of the 'Static Gateway' approach mentioned by Mauricio Scheffer. I don't know if this is a good design or not. I'm not a huge fan of it, I'd rather the dependency was injected more 'elegantly', though I can't use constructor injection obviously, I'd like to use Property injection but can't work out a way to hook into the ASP.NET MVC framework code to do this (I've even pored though the MVC2 source code).
I was able to wire it up [using Autofac as it happens, but it's just constructor injection via the ASP.NET MVC DependencyResolver] in this answer, enabling one to write:
class MyModel
{
...
[Required, StringLength(42)]
[ValidatorService(typeof(MyDiDependentValidator), ErrorMessage = "It's simply unacceptable")]
public string MyProperty { get; set; }
....
}
public class MyDiDependentValidator : Validator<MyModel>
{
readonly IUnitOfWork _iLoveWrappingStuff;
public MyDiDependentValidator(IUnitOfWork iLoveWrappingStuff)
{
_iLoveWrappingStuff = iLoveWrappingStuff;
}
protected override bool IsValid(MyModel instance, object value)
{
var attempted = (string)value;
return _iLoveWrappingStuff.SaysCanHazCheez(instance, attempted);
}
}
With some helper classes (look over there), you wire it up e.g. in ASP.NET MVC like so in the Global.asax :-
DataAnnotationsModelValidatorProvider.RegisterAdapterFactory(
typeof(ValidatorServiceAttribute),
(metadata, context, attribute) =>
new DataAnnotationsModelValidatorEx(metadata, context, attribute, true));
Hmm.
Can you test the effect of removing the (string message) ctor, and see if that at least forces Castle to use the ctor with the Repostiory ?
Otherwise we call AddComponent(name, type, type). Other than that it really should work...
Also does this hint at my first idea ? How do I use Windsor to inject dependencies into ActionFilterAttributes

Categories