Dependency injection everywhere
By Dawid on (tags: ASP.NET, dependency, injection, IoC, next, razor, categories: code)Just a few years ago there was just few people who known what dependency injection is. Today it is almost everywhere. Recently I’ve discovered that it can be also used in Razor views – thanks to ASP.NET 5.
I will try to show you how we can use that feature on few examples bellow.
Probably each of you have been populating drop downs in Razor views with data send from controller. I’ve been doing loot of time in following way:
1: public ActionResult GetUser()
2: { UserModel model = new UserModel();
3: //we can pass drop down items through model
4: model.WorkPositions = GetPositions()
5: //or by using ViewBag
6: ViewBag.WorkPositions = GetPositions();
7: return PartialView("UserDetails", model)
8: }
9:
10: private IEnumerable<SelectListItem> GetPositions()
11: {
12: ...
13: }
And then populate drop down in the Razor view like that:
1: @Html.DropDownListFor(x=>x.PositionId, (IEnumerable<SelectListItem>)ViewBag.WorkPositions)
2: or
3: @Html.DropDownListFor(m => m.PositionId, Model.WorkPositions)
There are two disadvantages of such approach in my opinion:
- nasty looking casting
- when you have lot of drop downs on the page, content of ViewBag can become messy
Thanks to new features of ASP.NET 5 we have another way to do the same thing – we can inject service directly into the view and use it to populate drop down. Take a look at this:
1: public interface IPosition
2: {
3: IEnumerable<Position> GetPositions();
4: }
5:
6: public class PositionService : IPosition
7: {
8: public IEnumerable<Position> GetPositions()
9: {
10: return new List<Position>
11: {
12: new Position { Id = 1, Name = "Senior Software Developer" },
13: new Position { Id = 2, Name = "Technical Lead" }
14: };
15: }
16: }
And here we have Razor view code:
1: @model ViewDependencyInjection.Models.User
2: @inject ViewDependencyInjection.Interfaces.IPositionService PositionService
3:
4: @{
5: Layout = "~/Views/Shared/_Layout.cshtml";
6: }
7:
8: <div>@Model.FistName</div>
9: <div>@Model.LastName</div>
10: <div>
11: @Html.DropDownListFor(m => m.WorkPositionId, PositionService.GetPositions().Select(p => new SelectListItem { Text = p.Name, Value = p.Id.ToString() }))
12: </div>
13:
14:
And that’s all – new approach, more generic (we can use the same service in different parts of the project), more dependency injection.