Dependant object as parameter to dependency in Autofac - asp.net-mvc

In broader terms what I am trying to achieve with Autofac is to pass the dependant (a.k.a. parent) object to its dependencies.
For example:
interface IDependency {}
class Dependant
{
IDependency Dependency { get; set; }
}
class ConcreteDependency : IDependency
{
ConcreteDependency(Dependant dependant) { /* ... */ }
}
I am hoping this could work, because Dependant breaks the dependency loop using property injection (meaning you can create an instance of Dependant, before having to resolve IDependency). Whilst, if both classes used ctor-injection this wouldn't be possible.
Specifically, I am trying to inject the current ASP.NET MVC controller instance to one of its dependencies.
Take a look at:
public abstract class ApplicationController : Controller
{
public ILogger Logger { get; set;}
}
public class SomeController : ApplicationController
{
[HttpPost]
public ActionResult Create(FormCollection formData)
{
// something fails...
this.Logger.Log("Something has failed.");
}
}
public interface ILogger
{
public void Log(string message);
}
public class TempDataLogger : ILogger
{
private ControllerBase controller;
public NullLogger(ControllerBase controller)
{
this.controller = controller;
}
public void Log(string message)
{
this.controller.TempData["Log"] = message;
}
}
In plain English the above code uses TempData as a way of "logging" messages (maybe to print it out in a nice way in view-layout or something...).
Simple enough all controllers are registered in Autofac:
builder.RegisterControllers(typeof(MvcApplication).Assembly)
.PropertiesAutowired(); // not strictly necessary
But then, how can I tweak the ILogger registration below to make it work?
builder.RegisterType<TempDataLogger>()
.As<ILogger>()
.InstancePerRequest();
Is this even possible in Autofac?
Thank you.

In case anyone else is interested, the solution below is the closest I was able to get so far:
builder.RegisterControllers(typeof(MvcApplication).Assembly)
.PropertiesAutowired() // not strictly necessary
.OnActivating(e => ((ApplicationController)e.Instance).Logger = new TempDataLogger((ApplicationController)e.Instance));
... and therefore, no need to;
builder.RegisterType<TempDataLogger>()
.As<ILogger>()
.InstancePerRequest();

Related

Autofac Dependency Injection - Set public property

I am building the asp.net WebAPI project and have used Autofac as IOC. Now i am doing constructor based injection and calls the various methods of the business class from the controller class.
Now i want to pass some additional data into the business class via the public property IncomingUser such as this one :-
My interface looks like this :-
public interface IUserManager
{
string IncomingUser { set; get; }
Task<List<String>> GetUserPofiles(string Name);
}
This readonly property IncomingUser will be used inside various methods defined under the class UserManager.
public class UserManager : IUserManager
{
public string IncomingUser { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
public async Task<List<String>> GetUserPofiles(string Name)
{
......Business Logic for the method......
}
}
From the API controller, i am setting the DI like this :-
public class myAPIController : ApiController
{
IUserManager _Manager;
public myAPIController(IUserManager Mang)
{
_Manager = Mang;
}
}
Please suggest, how should i set the property IncomingUser from the API controller class with the help of autofac DI or another way.

IoC - Autofac and register multiple services with same generic Interface

I have a service layer with the following classes / intefaces (IServices is an empty interface):
public interface IForoChanService<T> : IService
{
T GetById(int id);
IQueryable SearchBy(Expression<Func<T, bool>> predicate);
IEnumerable<T> GetAll();
int Create(T entity);
void CreateMany(IEnumerable<T> entities);
void Delete(T entity);
void Delete(int id);
void DeleteMany(IEnumerable<T> entities);
void Update(T entity);
}
Then I have an abstract class implementing that signature generically:
public abstract class ForoChanServiceBase<T> : IForoChanService<T> where T : EntityBase
{
public T GetById(int id)
{
return ChanDbContext.Set<T>().Find(id);
}
//all the other methods as well
}
And finally the concrete classes:
public class CategoryService : ForoChanServiceBase<Category>
{
}
I am trying to use AutoFac to inject those services (many: category, client, etc) in the constructor: I have a base controller:
public abstract class ForoChanBaseController: Controller
{
protected ForoChanServiceBase<Post> PostService { get; private set; }
protected ForoChanServiceBase<Comment> CommentService { get; private set; }
protected ForoChanServiceBase<Category> CategoryService { get; private set; }
protected ForoChanBaseController()
{
}
protected ForoChanBaseController(
ForoChanServiceBase<Post> postService,
ForoChanServiceBase<Comment> commentService,
ForoChanServiceBase<Category> categoryService)
{
PostService = postService;
CommentService = commentService;
CategoryService = categoryService;
}
}
And I am setting autofac like this:
public static void ConfigureIoc()
{
var builder = new ContainerBuilder();
builder.RegisterType<CommentService>().As<ForoChanServiceBase<Comment>>().InstancePerRequest();
builder.RegisterType<CategoryService>().As<ForoChanServiceBase<Category>>().InstancePerRequest();
builder.RegisterType<PostService>().As<ForoChanServiceBase<Post>>().InstancePerRequest();
builder.Build();
}
The problem is that I am having is when in the controller I need to use any service method that guy (CategoryService) is null:
public ActionResult Create()
{
var p = new PostFormNewVm
{
Categories = CategoryService.GetAll().Select(c => new CategoryVm { Id = c.Id, Title = c.Title })
};
return View(p);
}
Besides this error do am I doing something wrong? I can't make it work.
I tried with the inteface as well.
Your ForoChanBaseController contains multiple constructors, which is an anti-pattern. Because of the existence of this default constructor, there is a derived class that uses this constructor instead of the overloaded one, which is causing the dependencies to be null.
Although this default ctor is the cause for you to post the question here, there are more -less obvious problems- with your design:
Although you can remove the default constructor, prevent having this base class at all. Bases classes are often big Single Responsibility Principle violations and are either used to stuff in cross-cutting concerns or other utility functions. By having this base class derived types are forced to require dependencies that they might not even use at all. This complicates your code and complicates testing.
Since you have the IForoChanService<T> interface, consumers should not depend on the ForoChanServiceBase base class. As a matter of fact, the same advise as before holds: this base class should probably not exist at all.
The IForoChanService<T> is big generic tool box of methods where consumers only use one or two of those methods at a time. This means you are violating the Interface Segregation Principle.
IForoChanService<T> implementations are likely to violate the Liskov Substitution Principle, since there will be implementations that don't allow entities to be deleted. This will cause call to Delete to fail with an exception, instead of the Delete to not exist for that entity.

How to have SimpleInjector resolve viewmodel dependencies?

I'm trying to use SimpleInjector 2.7.3 (IoC container) within an Asp.Net MVC + Web API application.
I've had a couple of problems trying to set it up for both MVC and Web API on the same project until I found this link:
http://methoddev.com/blg/let-s-talk-software/310/simple-injector-in-asp-net-mvc-webapi
After following the link's example, here's what I got:
One of my Web API controllers:
public class UserController : BaseApiController
{
private readonly IUserService service;
public UserController(IUserService userService)
{
// I should point that IUserService is being injected correctly here
this.service = userService;
}
public IHttpActionResult Post(CreateUserRequest request)
{
return Ok();
}
}
The problem happens when I try to execute the Post operation. The CreateUserRequest class itself has a dependency.
public class CreateUserRequest : IValidatableObject
{
private readonly IValidator<CreateUserRequest> validator;
public CreateUserRequest(IValidator<CreateUserRequest> _validator)
{
// _validator is not being injected, I'm getting null here
validator = _validator;
}
public string SomeProperty { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
// My validation logic here must call the validator injected
// when the object was created.
return null;
}
}
I should point that IValidator is an interface from the FluentValidator package.
Anyway, when CreateUserRequest is instantiated the validator is null, which means it's not being injected.
When I'm creating the SimpleInjector Container I can see the type correctly registered, so I don't think that is a problem.
I did the following change to CreateUserRequest class:
public class CreateUserRequest : IValidatableObject
{
private readonly CreateUserRequestValidator validator;
// Changed here to the concrete class
public CreateUserRequest(CreateUserRequestValidator _validator)
{
validator = _validator;
}
// ...
}
So, I changed the interface to a concrete class and I'm still receiving a null there.
The only thing I can imagine is that this is somehow related to the custom dependency resolver suggested by the aforementioned link. I needed to use that in order to have the same dependency resolution logic for both MVC and Web API. Here's the code:
public class SimpleInjectorDependencyResolver : System.Web.Mvc.IDependencyResolver,
System.Web.Http.Dependencies.IDependencyResolver,
System.Web.Http.Dependencies.IDependencyScope
{
public SimpleInjectorDependencyResolver(Container container)
{
if (container == null)
{
throw new ArgumentNullException("container");
}
this.Container = container;
}
public Container Container { get; private set; }
public object GetService(Type serviceType)
{
if (!serviceType.IsAbstract && typeof(IController).IsAssignableFrom(serviceType))
{
return this.Container.GetInstance(serviceType);
}
return ((IServiceProvider)this.Container).GetService(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType)
{
return this.Container.GetAllInstances(serviceType);
}
IDependencyScope System.Web.Http.Dependencies.IDependencyResolver.BeginScope()
{
return this;
}
object IDependencyScope.GetService(Type serviceType)
{
return ((IServiceProvider)this.Container).GetService(serviceType);
}
IEnumerable<object> IDependencyScope.GetServices(Type serviceType)
{
return this.Container.GetAllInstances(serviceType);
}
void IDisposable.Dispose()
{
}
}
I don't really know a lot of the plumbing behind MVC and Web API (specially the custom dependency resolver feature), so, I'm really stuck on this one.
I appreciate any help figuring that out. Thanks.
--UPDATE--
In addition to the answer given by Steven, I would like to leave a link to whoever falls into the same problem. It's a great resource:
https://brettedotnet.wordpress.com/2014/07/16/web-api-and-interface-parameters/
The reason why your view model object isn't auto-wired by Simple Injector is because both MVC and Web API don't build view model objects using the IDependencyResolver. So creating a special dependency resolver won't work. If you want to let your view models to be auto-wired, you will have to override the default model binder in MVC and Web API.
But I urge you not to do this. In my opinion, a model binder should just do data conversion and a view model should be a plain DTO. Although it is fine to mark view models with validation attributes, letting them have behavior using services that might even trigger any database communication is a big no-no in my book. This can complicate development tremendously.
This however means that this validator should be injected elsewhere. Without making any changes to your architecture, this basically means you will have to inject that validator in the controller instead:
public class UserController : BaseApiController
{
private readonly IUserService service;
private readonly IValidator<CreateUserRequest> validator;
public UserController(IUserService userService,
IValidator<CreateUserRequest> validator)
{
this.service = userService;
this.validator = validator;
}
}
Obviously this can easily complicate your controllers with extra dependencies and logic, but that's because validation is a cross-cutting concern that you would like to probably keep out of your controllers.
If you try to address this, you will eventually end up with a message passing architecture such as described here.

MVC Repository with Unit Of Work, Automapper and Generic Repository

I've been looking at a few blog posts to try and create an appropriate solution for the following requirements but I can't seem to piece them together. Hope fully someone can help.
I've been using Repository pattern with interfaces using Automapper...here's a trimmed down example:
public class BookingRepository : IBookingRepository
{
Entities context = new Entities();
public IEnumerable<BookingDto> GetBookings
{
get { return Mapper.Map<IQueryable<Booking>, IEnumerable<BookingDto>>(context.Bookings); }
}
public BookingDto GetBookingWithProduct(Guid bookingId)
{
return Mapper.Map<BookingDto>(context.Bookings.Include(c => c.Products).SingleOrDefault(c => c.BookingId == bookingId));
}
public void Update(BookingDto bookingDto)
{
var booking = Mapper.Map<Booking>(bookingDto);
context.Entry(booking).State = EntityState.Modified;
}
public void Save()
{
context.SaveChanges();
}
public void Dispose()
{
context.Dispose();
}
}
public interface IBookingRepository : IDisposable
{
IEnumerable<BookingDto> GetBookings { get; }
BookingDto GetBooking(Guid bookingId);
void Update(BookingDto bookingDto);
void Save();
}
With a seperate Repository for a different Entity, for example
public class ProductRepository : IProductRepository
{
Entities context = new Entities();
public IEnumerable<ProductDto> GetProducts
{
get { return Mapper.Map<IQueryable<Product>, IEnumerable<ProductDto>>(context.Products); }
}
public ProductDto GetProductWithDesign(int productId)
{
return Mapper.Map<ProductDto>(context.Products.Include(c => c.Designs).SingleOrDefault(c => c.ProductId == productId));
}
public void Update(ProductDto productDto)
{
var product = Mapper.Map<Product>(productDto);
context.Entry(product).State = EntityState.Modified;
}
public void Save()
{
context.SaveChanges();
}
public void Dispose()
{
context.Dispose();
}
}
public interface IProductRepository : IDisposable
{
IEnumerable<ProductDto> GetProducts { get; }
ProductDto GetProduct(int productId);
void Update(ProductDto productDto);
void Save();
}
Then in my Controller I'm using the repositories as so:
public class HomeController : Controller
{
private readonly IBookingRepository bookingRepository;
private readonly IProductRepository productRepository;
public HomeController() : this(new BookingRepository(), new ProductRepository()) { }
public HomeController(IBookingRepository bookingRepository, IProductRepository productRepository)
{
this.bookingRepository = bookingRepository;
this.productRepository = productRepository;
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing && this.bookingRepository != null)
this.bookingRepository.Dispose();
if (disposing && this.productRepository != null)
this.productRepository.Dispose();
}
}
So now I'm hoping to create a Unit Of Work to abstract these repositories and share the context and also create a generic repository for the duplicated actions (Save and Update) bearing in mind I'm passing in Dtos and Mapping to Entity objects. I'm having difficulty understanding how to knit it all together.
Additionally, I've seen this post
Repository pattern with generics and DI
which states "You should not have other repository interfaces besides your generic repository" and that custom queries "deserve their own (generic) abstraction:" which is adding another complication to my overworked brain as my repositories will have custom queries that return complex linked objects using Include Statements as Lazy Loading is disabled.
So I'm prepared to be shot down and told that I'm going about this the wrong way but would be grateful for any direction given.
Thanks in advance.
Don't use generic repositories. They are all leaky abstractions. Ask yourself, what benefit to you get by using an abstraction that doesn't really abstract away something? You could use your OR/M directly in those cases.
What I means is that anything that exposes IQueryable<T> forces the user to learn about the weaknesses that the underlying OR/M has. Examples: How do the orm handle lazy loading? How do I eagerly load related entities? How do I create a IN clause?
If you truly want to use the repository pattern either use it together with the specification pattern (you can keep on using a generic repository then) or create repositories that are specific for each root aggregate.
I've blogged about it: http://blog.gauffin.org/2013/01/repository-pattern-done-right/
What I usually do in this case is to create a Base abstract Repository class like this:
public abstract class BaseRepository<T> : IRepository<T>
{
Entities context = new Entities();
public virtual T GetAll()
{
return context.Set<T>();
}
// Add base implementation for normal CRUD here
}
If you don't need special queries then you don't need to create special interface and classes (but you can of course, to improve readability). So you will use, for example:
var bookingsRepo = new BaseRepository<BookingsDto>();
var allBookings = bookingsRepo.GetAll();
If you need some special queries, you create an interface that extends the base interface:
public interface IProductRepository : IRepository<Product>
{
Product GetSpecialOffer();
}
Then create your class:
public class ProductRepository : BaseRepository<Product>, IProductRepository
{
public Product GetSpecialOffer()
{
// your logic here
}
}
That way you only specify a minimal number of special cases while relying on the Base abstract implementation for all things normal.
I added virtual to the base methods because I always like to give derived class the ability to override stuff...

Initialize BaseController's fields using HttpContext, controller design

I need to setup a policy in base controller that applies to all controller instance, like below:
public class BaseController : Controller
{
private IPolicy Policy;
public BaseController()
{
this.Policy= new Policy(HttpContext);
}
}
Within the Policy class, I need to do something like:
this.httpContextBase.User.
Questions: (Update)
What is the better way to design the BaseController in terms of using HttpContext and Unit test.
What is the correct way to unit test HttpContext?
Absolutely no way. You are using the HttpContext inside the constructor of a controller when this context is still not initialized. Not only that this code cannot be tested but when you run the application it will also crash with NRE. You should never use any HttpContext related stuff in a constructor of a controller.
One possibility is to refactor your code and perform this inside the Initialize method:
public class BaseController : Controller
{
private IPolicy Policy;
protected override void Initialize(RequestContext requestContext)
{
base.Initialize(requestContext);
this.Policy = new Policy(HttpContext);
}
}
This being said, that's not the approach I would recommend. I would recommend you using dependency injection instead of service location which is considered by many as an anti-pattern.
So:
public abstract class BaseController : Controller
{
protected IPolicy Policy { get; private set; }
protected BaseController(IPolicy policy)
{
Policy = policy;
}
}
Now, all that's left is to configure your favourite Dependency Injection framework to inject the correct instance into the constructor. For example with Ninject.Mvc3 this is achieved with a single line of code:
kernel.Bind<IPolicy>().To<Policy>();
Now you can feel more than free to mock this IPolicy in your unit test without even caring about any HttpContext.
For example let's suppose that you have the following controller that you want to unit test:
public class FooController : BaseController
{
public FooController(IPolicy policy): base(policy)
{ }
[Authorize]
public ActionResult Index()
{
Policy.DoSomething();
return View();
}
}
Now, all that you need to do is pick up your favorite mock framework (Rhino Mocks in my case) and do the mocking:
[TestMethod]
public void Index_Action_Should_DoSomething_With_The_Policy()
{
// arrange
var policyStub = MockRepository.GenerateStub<IPolicy>();
var sut = new FooController(policyStub);
// act
var actual = sut.Index();
// assert
Assert.IsInstanceOfType(actual, typeof(ViewResult));
policyStub.AssertWasCalled(x => x.DoSomething());
}

Resources