IoC - Delay initialization of services in controller until required - asp.net-mvc

In an ASP.NET MVC application, I'm calling "Services" methods from my controllers.
Usually, a controller named ReportingController calls methods from ReportingServices. The service classes are being instantiated with Autofac with the Mvc.Integration.
builder.RegisterControllers(Assembly.GetExecutingAssembly());
The service is then injected into the controller constructor.
public ReportingController(ReportingServices service)
So far so good.
But occasionally, a controller needs to call methods from other services. I changed the autofac configuration:
builder.RegisterControllers(Assembly.GetExecutingAssembly())
.PropertiesAutowired(PropertyWiringOptions.PreserveSetValues);
And added properties to the controllers:
public CommonServices CommonService { get; set; } // new properties
public ReportingController(ReportingServices service) {} // existing ctor
What happens now however is that when the controller is instantiated, all properties are also being set, even if they are never used by a particular ActionMethod.
How can I tell Autofac to delay instantiation of the properties until required or perhaps I should simply not care about this unnecessary initialization?

Autofac supports Lazy<T> out of the box.
So you just need to declare your property as:
public Lazy<CommonServices> CommonService { get; set; }
And Autofac won't instantiate your CommonServices until you don't access your Lazy's value with CommonService.Value.

Related

Manually inject service in asp.net core mvc6?

I want to use DI to manually inject an IDBConnection in my api controllers. I know I can put it in the constructor:
public MyController(IDBConnection cnn) { this._Connection = cnn; }
Or I could use the [FromServices] attribute:
[FromServices]
public IDbConnection _Connection { get; set; }
And I can use it in views like this:
#inject IDbConnection cnn
What I would really like to do would be to have it in a using, and have the DI open the connection so I could do something like this:
using (var cnn = Services.Inject<IDbConnection>()) {
// do something, don't worry about opening or closing
}
I'm declaring it like this:
services.AddTransient<IDbConnection>(x =>
{
string connectionString = Configuration.Get<string>(
"Data:DefaultConnection:ConnectionString");
return new SqlConnection(connectionString);
});
Should I create a class inheriting from SqlConnection that calls Open() in it's constructor? How can I access Configuration from there? I could create it like that to inject configuration or the connect string... Is using not required? Is there basically no overhead with just creating the instance so it wouldn't matter if some actions needed multiple connections to different databases?
I recommend that you create a service layer that your controller will depend on instead of directly accessing the db connection (and you won't have to this in your views #inject IDbConnection cnn). Your views should only declare the Model that your controller method returns and you will have nice intellisense support in the view pages.
public class ProductServices(){
public ProductServices(IDbConnection conn){
...
}
public List<Product> GetProducts(){
...
}
}
using is not required. As a rule of thumb, if the instance is created via IoC container (eg. Unity, Autofac, Ninject, etc), it should also be destroyed by the IoC container.

unity.mvc4: how to get a reference

I've setup Unity in Bootstrapper.cs of my MVC application, all is working well for constructor injection on my controllers...
My question is when I'm in an ActionResult within a controller I need to get a reference to the container I previously created in Bootstrapper.cs so I can use it to resolve classes for me.
e.g:
public ActionResult Index()
{
//-- container needs a reference to unity container
var testService = container.Resolve<ITestService>();
return View(testService);
}
I need to get a reference to the container
No you don't. You should never need to reference the container (or the DependencyResolver) from within your application.
Use constructor injection instead:
public class HomeController : Controller
{
private readonly ITestService testService;
// constructor
public HomeController(ITestService testService)
{
this.testService = testService;
}
public ActionResult Index()
{
return View(this.testService);
}
}
Since you are using the MVC3 integration package for unity, you probably registered a Unity specific DependencyResolver in the startup path of your application. That looks much like this:
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
When you've done this, your custom DependencyResolver will delegate the creation of controllers to the Unity container and the Unity container is able to inject depdencies of the constructor's of the controllers.
The next thing you should never do is letting views do any work and making them dependent on your services. Views should be dumb and do nothing more than map the data they get from the controller and transform them to HTML (or JSON or whatever).
In other words, do not pass on the testService to the view. Calling the testService from within the view hides that logic, makes the view more complicated, and makes the system hard to test. Since you're using an ITestService abstraction, I assume you want to be able to test your code, but testing the view is not easy (or at least, not as easy as you can test the controller).
What you should do is let the controller call the testService and gather the data that is needed for the view to use. Than pass on that data (perhaps combined in a single class, a view model) to the view.

.NET MVC - where to use dependency injection?

I'm currently injecting dependencies into controllers using a IoC container (Castle). This is possible because you need to create a custom controller factory which enables the dependency injection.
What are other examples of dependency injection? At which point in an MVC application would you use it, and where does a 'factory' come into play?
I am using Ninject. At my project:
Service layer objects are injected into controllers (using constructor).
Repositories are injected into service layer objects (using constructor).
ObjectContext is injected into repositories (using constructor).
web.config setting are encapsulated into a class, which implements IAppSettings interface, which is then injected into service layer.
NinjectActionInvoker is injected as IActionInvoker. It takes care of injecting services into ActionFilters.
I have my own implementation of IPrincipal interface, which is injected into service layer, instead of referring to HttpContext.Current.User.
Example using Ninject:
public class UserService : GenericService<User>, IUserService
{
public ISettingService SettingService { get; set; }
public ICTEmailSender CTEmailSender { get; set; }
public ICTSettings CTSettings { get; set; }
public ICTPrincipal User { get; set; }
}
Ninject rules:
Bind<ICTPrincipal>().ToMethod(c => (ICTPrincipal)HttpContext.Current.User).OnlyIf(a => HttpContext.Current.User is ICTPrincipal);
Bind<ICTEmailSender>().To<CTEmailSender>();
Bind<ICTSettings>().To<CTSettings>();
Not only service is injected into controller, but parts of service are injected into it. It makes service more testable. I am sure it can be easily ported into Castle.

Using Ninject with Membership.Provider

I'm new to Ninject and I'm having problems using it with a custom membership provider.
My membership provider has a repository interface passed in. It looks like:
public class CustomMembershipProvider : MembershipProvider
{
public CustomMembershipProvider( IRepository repository )
{
}
}
I'm using the code thats part of the Account Model in the MVC app as a starting point.
However when it calls Membership.Provider I get an error saying No parameterless constructor defined for this object.
I've setup the bindings in ninject to bind a IRepository to a Repository class which work as I've testing this in a controller.
What are the correct bindings in Ninject to use for Membership.Provider?
This is how it should be done today with new versions of both MVC and Ninject (version 3):
You have access to the DependencyResolver instance and Ninject sets itself as the current DependencyResolver. That way you don't need hacks to get access to the static Ninject kernel. Please note, my example uses my own IUserService repository for Membership...
IUserService _userService = DependencyResolver.Current.GetService<IUserService>();
The best solution I found was the following:
private IRepository _repository;
[Inject]
public IRepository Repository
{
get { return _repository; }
set { _repository= value; }
}
public CustomMembershipProvider()
{
NinjectHelper.Kernel.Inject(this);
}
Where NinjectHelper is a static helper class to get the Kernal from.
Since the membership collection and the Membership.Provider instance are created before Ninject can instantiate them, you need to perform post creation activation on the object. If you mark your dependencies with [Inject] for your properties in your provider class, you can call kernel.Inject(Membership.Provider) - this will assign all dependencies to your properties.
I haven't used Ninject ever.
but in StructureMap i set this dependency:
expression.For<MembershipProvider>().Add(System.Web.Security.Membership.Provider);
and it works fine.

Why are there 2 constructors in the Default AccountController provided by the MVC?

here's the default AccountController.cs that's generated by the framework.
public class AccountController : Controller
{
public IFormsAuthentication FormsAuth { get; private set; }
public IMembershipService MembershipService { get; private set; }
public AccountController()
: this(null, null)
{
}
public AccountController(IFormsAuthentication formsAuth, IMembershipService membershipService)
{
FormsAuth = formsAuth ?? new FormsAuthenticationService();
MembershipService = membershipService ?? new AccountMembershipService();
//---
}
This is easy to understand.
public AccountController(IFormsAuthentication formsAuth,
IMembershipService membershipService)
{
FormsAuth = formsAuth ?? new FormsAuthenticationService();
MembershipService = membershipService ?? new AccountMembershipService();
}
What's this? What's its purpose? Is it particular to the Account Controller or is it a requirement for other controllers? and, why should I incorporate it in my project?
public AccountController()
: this(null, null)
{
}
They seem to use this type of constructors in two other places.
Thanks for helping
This is actually an implemenation of the Bastard Injection anti-pattern.
The idea is that Constructor Injection is supported to allow Dependency Injection (DI), while still providing a default constructor for default behavior.
It's really not necessary to have the default constructor, but if you omit it, you must supply a custom IControllerFactory, as the DefaultControllerFactory assumes that all Controllers have default constructors.
ASP.NET MVC is built with DI in mind, but I guess that to keep it simple, the Bastard Injection pattern was used for the project template to avoid forcing a specific IControllerFactory upon developers.
If you use a DI framework (like Unity) and you active your controllers via the container, it might not find the dependencies and use the default constructor (in this case).
If you would like use use generics, something like ... where T : IController, new() you will need a default constructor.
Another reason for having a default (no parameter) constructor is for Reflection.
The classes in the System.Reflection namespace, together with Type, allow you to obtain information about loaded assemblies and the types defined within them, such as classes, interfaces, and value types. You can also use reflection to create type instances at run time, and to invoke and access them.
There might be times where you need to create a temporary object of that type in order to reflect over it's properties or methods, but don't want or need the overhead of creating a real object - especially if that entails accessing a database or remote service for example.

Resources