MVP Autofac and Controllers - c#

I have a page like so -
public partial class ProductDetailMixed : SessionPage, IProductDetailMixedView
{
public IProductService ProductService { get; set; }
protected void Page_Load(object sender, EventArgs e)
{
Controller = new ProductDetailMixedController(this, ProductService);
OnLoadPage();
}
public event LoadPageEvent OnLoadPage;
public IProductDetailMixedController Controller { get; set; }
}
I have property injection so the instance of IProductService will be injected into the page, however what I would really like is to just create the controller like so -
Controller = new ProductDetailMixedController(this);
And then the Constructor of ProductDetailMixedController will just inject all the remaining parameters.. but how do I do this??

I believe this is what you're trying to accomplish? In the referenced example, your presenter / controller factory would also need a parameter for your service interface. Once you have something like that in place, you could remove the property injection for your service from your view (unless you utilize it within your view, of course).

Related

Dependency Injection pass parameters by constructor

We have a project where we need to use DI and ASP Core.
I'm very new to this and have a question.
I have a controller named HomeController like this:
public class HomeController : BaseController {
private IOrderService _orderService;
public HomeController(IOrderService orderService) {
_orderService = orderService;
}
public IActionResult Index() {
var orders = _orderService.GetMyOrders();
return View(orders);
}
}
The code looks like this:
public class OrderService : BaseService, IOrderService {
public OrderService(IDataContextService dataContextService) {
_dataContextService = dataContextService;
}
public List<Orders> GetMyOrders() {
var orders = // do my code here which works fine!;
// here i need some code do check orders for delivery so
DeliveryService deliveryService = new DeliveryService(_dataContextService);
// update my orders and return these orders
return orders;
}
}
public class DeliveryService : BaseService, IDeliveryService {
public DeliveryService(IDataContextService dataContextService) {
_dataContextService = dataContextService;
}
public void MyMethod() {
}
}
public class BaseService {
protected IDataContextService _dataContextService;
}
Almost all my services have a constructor like the OrderService and DeliveryService. My question is, do I have to pass the _dataContextService every time, or is there a solution within the dependency pattern?
You should keep it the way you have it and asp.net core IoC will inject it for you, but make sure it is injected per request, this will help to insantiate only one context for each request and dispose it after the request is served.
You can register the context and services in the ConfigureServices method inside the Startup class as below
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
// Add application services.
services.AddTransient<HomeController>();
services.AddTransient<IOrderService , OrderService >();
services.AddTransient<IDeliveryService, DeliveryService>();
services.AddScoped<IDataContextService , YourDataContextService >();
}
The AddScoped method will create only one instance of the object for each HTTP request
If I understand correctly what you are asking, you are looking for an IoC container. .NET Core has built in support for dependency injection. Basically, you just indicate which implementation should be provided when an interface is requested. Then the container will instantiate the types for you. See for example https://learn.microsoft.com/en-us/aspnet/core/mvc/controllers/dependency-injection.
Hope that helps

Create instance of interface with dependency injection

I have a base controller and before every page load I want to get the current user. I originally had a constructor in my BaseController that looked like this
public BaseController(ISystemUserCommand command)
{
_systemUserCommand = command
}
The problem with this then is that every controller that inherits from the BaseController would have to contain the ISystemUserCommand in its constructor, which I don't think would be good.
Instead I tried to create just an instance of the service class (shown below - it's the commented line under var sid...) but I need to pass in user service. How would I pass in the user service here or is this a bad way of doing it?
public abstract class BaseController : Controller
{
public SystemUserViewModel CurrentUser { get; set; }
private readonly ISystemUserCommand _systemUserCommand;
public SystemUserViewModel GetCurrentUser()
{
if (HttpContext == null || HttpContext.User == null) return null;
if (CurrentUser != null) return CurrentUser;
var sid = System.Web.HttpContext.Current.Request.LogonUserIdentity.User.ToString();
//var command = new SystemUserCommand();
CurrentUser = _systemUserCommand.GetUser(sid);
return CurrentUser;
}
public void SetUserInformation(SystemUserViewModel currentUser)
{
ViewBag.UserId = currentUser.SystemUserId;
ViewBag.FullName = string.Format("{0} {1}", currentUser.FirstName, currentUser.LastName);
ViewBag.FirstName = currentUser.FirstName;
ViewBag.LastName = currentUser.LastName;
ViewBag.CurrentUser = currentUser;
}
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
var currentUser = GetCurrentUser();
if (currentUser != null)
{
if (currentUser.IsActive)
{
SetUserInformation(currentUser);
}
else
filterContext.Result = RedirectToAction("denied", "unauthorized");
}
else
filterContext.Result = RedirectToAction("denied", "unauthorized");
base.OnActionExecuting(filterContext);
}
}
public class SystemUserCommand : ISystemUserCommand
{
private readonly ISystemUserBusiness _systemUserBusiness;
public SystemUserCommand(ISystemUserBusiness systemUserBusiness)
{
_systemUserBusiness = systemUserBusiness;
}
...
}
You could use property injection instead of constructor injection, via the base class, eg using unity:
public abstract class BaseController : Controller
{
[Dependency]
public ISystemUserCommand SystemUserCommand { get; set; }
}
This would mean the interface reference is only on the base class.
See here for the full examples.
EDIT, Autofac example:
You don't need property attributes on the dependency,
public abstract class BaseController : Controller
{
public ISystemUserCommand SystemUserCommand { get; set; }
}
Just to register the properites to auto resolve on the autofac builder:
builder.RegisterControllers(typeof(MvcApplication).Assembly).Where(t => t.IsAssignableFrom(typeof(BaseController))).PropertiesAutowired();
See autofac property injection here.
First of all, it does not seem a good idea to have OnActionExecuting override in the controller. You can use filters, that are specially designed for this purpose. And it seems that is the main reason you created the BaseController at all.
Regarding the problem with injecting the system command in all the required service, I would do so, but without inheriting from a base class, since I generally prefer aggregation to inheritance. That would mean that each controller that needs to work with the service will get it.
Another option that I have used few times to abstract some operations is to create a UserSerivce that will provide the required operations to the controllers. It will have ISystemUserCommand and HttpContext injected inside so that all of your controllers won't have to do the job. You can either use HttpContext.Current as static or abstract it away if you need testability.
Moreover I would not recommend property injection since it is more obscure than constructor injection that should be preferred if possible.
You can read more about filters here. Unfortunately if you use filters it's not that easy to inject in filters themselves and mostly done with property injection or ServiceLocator pattern (which is not good usually). It's possible to do better with some amount of voodoo though. I think that SimpleInjector has a lot of examples and tutorials on how to apply DI to filters in MVC, maybe they even have a nuget package now to ahieve that.

Dependency injection (DI) in ASP.Net MVC 6

i was reading a write up on easily dependency injection in ASP.Net MVC 6 from this url http://weblogs.asp.net/scottgu/introducing-asp-net-5
they show how very easily we can inject dependency into project
1st one
namespace WebApplication1
{
public class TimeService
{
public TimeService()
{
Ticks = DateTime.Now.Ticks.ToString();
}
public String Ticks { get; set; }
}
}
register the time service as a transient service in the ConfigureServices method of the Startup class:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddTransient<TimeService>();
}
public class HomeController : Controller
{
public TimeService TimeService { get; set; }
public HomeController(TimeService timeService)
{
TimeService = timeService;
}
public IActionResult About()
{
ViewBag.Message = TimeService.Ticks + " From Controller";
System.Threading.Thread.Sleep(1);
return View();
}
}
2nd one
public class HomeController : Controller
{
[Activate]
public TimeService TimeService { get; set; }
}
now see the second code. are they trying to say that if we use [Activate] attribute then we do not have to instantiate TimeService by controller constructor injection?
just tell me if we use [Activate] attribute then what will be the advantage ?
if we use [Activate] attribute then what line of code we can eliminate from 1st same code. thanks
The differences between the two code blocks are indeed that the first one leverages Constructor Injection to resolve the dependency on TimeService, while the second example marks a property as one that needs resolving using Property Injection.
What this means is simply that the following constructor becomes redundant:
public HomeController(TimeService timeService)
{
TimeService = timeService;
}
As to why one would opt for Constructor versus Property Injection, I find that trying to have a list of your dependencies clearly listed out in your constructor highlights when a class becomes too dependent, which raises concerns as to what a class is trying to accomplish and, subsequently, makes it a candidate for refactoring.
Property Injection via [Activate] will not be supported from beta5 onwards.

C# Dependency Injection passing additional parameter

I have a class similar to the following:
public class CarAttributes
{
private readonly ICarRepository _carRepository;
private readonly int _carId;
public CarAttributes(ICarRepository carRepository, int carId)
{
_carRepository = carRepository;
_carId = carId;
}
public bool IsRegistered
{
get
{
return _carRepository.IsRegistered(_carId);
}
}
public bool IsStolen
{
get
{
return _carRepository.IsStolen(_carId);
}
}
}
I also have the following method (which is syntactically incorrect)
public CarAttributes GetCarAttributes(int carId)
{
return new CarAttributes(carId);
}
I am using Unity to inject the ICarRepository at runtime
container.RegisterType<ICarRepository, CarRepository>();
How do I inject CarAttributes with the CarRepository via Unity but allow the program to supply the carId?
Am I correct in thinking that i need a factory to do this?
Something perhaps like the following
public class CarAttributesFactory()
{
private readonly ICarRepository _carRepository;
public CarAttributesFactory(ICarRepository carRepository)
{
_carRepository = carRepository;
}
public CarAttributes GetCarAttributes(int carId)
{
return new CarAttributes(_carRepository, carId);
}
}
This allows unity to inject the factory with the dependency, but will also allow the program to specify the carId when the GetCarAttributes method is invoked.
However is this not going against the DI principles, as I am creating a dependency here between the CarAttributesFactory and the CarAttributes classes.
Is this the correct usage for using factories?
Also I have read about other DI frameworks having things such as TypedFactories for this kind of thing, although I would like to do it manually first to understand the concepts.
Here for example
Unity - Constructor Injection with other parameter
Hope this makes sense.
EDIT: Example usage
From my MVC controller I need to be able to retrieve back a CarAttributes object for a specific carId which will be passed in via a view model. The CarAttributes class requires the use of one or more repositories (only one shown in this example), as well as a run time parameter passed in which is carId depending on what comes though the view model.
(I would also have to create an ICarAttributesFactory interface as well in order to inject the factory into the controller in the below example)
public SomeController : Controller
{
private readonly ICarAttributesFactory _carAttributesFactory;
public SomeController(ICarAttributesFactory carAttributesFactory)
{
_carAttributesFactory = carAttributesFactory;
}
public ActionResult Submit(DataViewModel model)
{
// model will contain a carId property
var carAttribs = _carAttributesFactory.GetCarAttributes(model.carId);
if(carAttribs.IsStolen)
{
// do something
}
}
}

How can I spread custom object through my MVC application?

Let say I have an object that is similar for each user that try to access to my website.
A sort of Session Scope object, which should be visible on every View/Model/Controller inside my whole "application".
I'd like to create it when I call a page and populate it through data coming from my own database.
Than, on View (as example) calling myObject.Title.
On WebForms I'm doing this extending a class of the UserControl, such as:
public class iUserControl : System.Web.UI.UserControl
{
protected MyCurrentPage myCurrentPage;
public iUserControl()
{
}
protected override void OnLoad(EventArgs e)
{
myCurrentPage = new MyCurrentPageWrapper();
}
}
than, for each UserControl, somethings like this:
public partial class context_pippo_MyOwnUserControl : iUserControl
on MVC I can't see any extension for each controls, so how can I could achieve this kind of process? I'd like to get rid about storing elements on Session.
If I understand question correctly, I think I've done something similar in one project.
I had something like this:
public interface IControllerBaseService
{
IUserService UserService {get;set;}
ShoppingMode ShoppingMode {get;set;}
...
}
public abstract class ControllerBase : Controller, IControllerBaseService
{
public IUserService UserService {get;set;} // this is injected by IoC
public ShoppingMode ShoppingMode
{
get
{
return UserService.CurrentShoppingMode; // this uses injected instance to get value
}
...
}
As long, as I user IoC container to create controller instances, UserService property is injected by container.
You can access now your interface from view like this:
(IControllerBaseService)ViewContext.Controller
To have a shortcuts for most common used properties in IControllerBaseService, I had several extension methods, something like this:
public static ShoppingMode CurrentShoppingMode(this HtmlHelper helper)
{
return ((IContollerBaseService)helper.ViewContext.Controller).ShoppingMode;
}
So in view it looked like #Html.CurrentShoppingMode()

Categories

Resources