I am creating an instance of a type scoped to HTTPContextScoped. I am trying to figure out how to inject this specific instance into a property of the same type into an attribute that I don't have control over.
I want to inject the specific instance of UnitOfWork into a property of IUnitOfWork type in an attribute (see code below)
Here is my ObjectFactory.Initialize() method of the part that I am referring to:
ObjectFactory.Initialize(x =>
{
//...
//additional content
//...
x.For<IUnitOfWork>()
.HttpContextScoped()
.Use(context => new UnitOfWork(
context.GetInstance<ISessionFactory>()));
x.SetAllProperties(context =>
{
context.Matching(p =>
p.DeclaringType == typeof(UnitOfWorkAttribute));
context.OfType<IUnitOfWork>();
});
Attribute Class:
public class UnitOfWorkAttribute : ActionFilterAttribute {
public IUnitOfWork UnitOfWork { get; set; }
public UnitOfWorkAttribute() {
Order = 0;
}
public void OnActionExecuting(ActionExecutingContext filterContext) {
UnitOfWork.Begin();
}
public void OnActionExecuted(ActionExecutedContext filterContext) {
UnitOfWork.End();
}
}
I was trying to follow one of Jeremy Miller's examples of using criteria to do so, but I am not doing something right.
Any thoughts of what I am doing incorrectly?
NOTE It does create the UnitOfWork instance as I use it else where, but I am specifically not correctly (or at all) injecting this attribute's property with that instance (or any for that matter).
Try solving this problem by creating a factory for IUnitOfWork objects. Since the lifetime of unit of work instances must be controlled explicly (since you are doing Begin and End, controlling them yourself is much more logical, and adheres the principle of least surprise.
Here is an example of what you can do:
public interface IUnitOfWorkFactory
{
IUnitOfWork NewUnitOfWork();
}
public class MyController : Controller
{
private readonly IUnitOfWorkFactory factory;
public MyController(IUnitOfWorkFactory factory)
{
this.factory = factory;
}
public void Operation()
{
using (var work = new this.factory.NewUnitOfWork())
{
work.Begin();
// do some interesting stuff here.
work.End();
}
}
}
Related
I have the follow trouble, in my base controller i do dependency injection. And i have a class child with implementation of base controller and i need pass the constructor. So my doubt is, my way to implementation of dependency injection is correctly?
If no, what is the best way to do this?
I use unity to implementate D.I, and my ide is VS2017 web api 2.
Follow this code i using:
Base controller or parent controller:
public class BaseController : ApiController
{
public string[] includes = null;
private readonly IFiltroServico servico;
public BaseController(IFiltroServico _servico)
{
servico = _servico;
}
}
Base controller to generics types implements Base Controller:
public abstract class BaseController<E, R, F> : BaseController
where E : class
where R : class
where F : class
{
private readonly IFiltroServico servico;
public AreaFormacaoController(IFiltroServico _servico): base(_servico)
{
servico = _servico;
}
}
Child controller:
public abstract class BaseController<R> : BaseController
where R : class
{
private readonly IFiltroServico servico;
public AreaFormacaoController(IFiltroServico _servico): base(_servico)
{
servico = _servico;
}
//services of controller;
}
You don't need to define the private field servico over and over again as it is already preset in the base controller. Just define it as protected readonly in the base class and use it in the childs.
Other than that your code is fine.
It is perfectly reasonable that a child has the same dependency parameters in the constructor as it inherits behavior of the base class that is most likely relying on the dependency.
Another option would be to use property injection in the base class but you need to add a unity specific attribute to the property. I don't like that as you bind your code directly to Unity.
Have you seen https://simpleinjector.org/index.html
check out git from https://github.com/simpleinjector/SimpleInjector
It is one of the best Inversion of Control library (IOC).
Only thing you need to do is register all your services and types.
using SimpleInjector;
static class Program
{
static readonly Container container;
static Program() {
// 1. Create a new Simple Injector container
container = new Container();
// 2. Configure the container (register)
container.Register<IOrderRepository, SqlOrderRepository>();
container.Register<ILogger, FileLogger>(Lifestyle.Singleton);
container.Register<CancelOrderHandler>();
// 3. Verify your configuration
container.Verify();
}
static void Main(string[] args)) {
// 4. Use the container
var handler = container.GetInstance<CancelOrderHandler>();
var orderId = Guid.Parse(args[0]);
var command = new CancelOrder { OrderId = orderId };
handler.Handle(command);
}
}
Once you register all your types and services you can inject those services where ever you want
public class CancelOrderHandler {
private readonly IOrderRepository repository;
private readonly ILogger logger;
private readonly IEventPublisher publisher;
// Use constructor injection for the dependencies
public CancelOrderHandler(
IOrderRepository repository, ILogger logger, IEventPublisher publisher) {
this.repository = repository;
this.logger = logger;
this.publisher = publisher;
}
public void Handle(CancelOrder command) {
this.logger.Log("Cancelling order " + command.OrderId);
var order = this.repository.GetById(command.OrderId);
order.Status = OrderStatus.Cancelled;
this.repository.Save(order);
this.publisher.Publish(new OrderCancelled(command.OrderId));
}
}
public class SqlOrderRepository : IOrderRepository {
private readonly ILogger logger;
// Use constructor injection for the dependencies
public SqlOrderRepository(ILogger logger) {
this.logger = logger;
}
public Order GetById(Guid id) {
this.logger.Log("Getting Order " + order.Id);
// Retrieve from db.
}
public void Save(Order order) {
this.logger.Log("Saving order " + order.Id);
// Save to db.
}
}
Let me know if you have any queries, Thanks.
I have a WebApi project using Entity Framework 6.0, Autfac for DI and CQRS architecture. The problem I have that DbContext isn't disposing how it supposed to. The action I take:
I run two quick requests, e.g. send request from Postman to one endpoint, runtime stops on breakpoint in controller method, I send second request to another endpoint in different controller.
Resume Runtime
if the second request finished before the first one is done, the first one throws and error that dbcontext was disposed and it cannot run whatever it was supposed to do
Originally problem appeared when I posted and patched from frontend one after another.
It seems like lifetime scope is not really per-request. It seems like all dbcontexts are disposed on one of the request's end. The other one does not have anything to work with.
How is it configured?
Starting from the highest layer - controller:
public class UsersController : BaseController, IUsersApi
{
private readonly IUserService _userService;
public UsersController(IUserService userService, ILogging logging) : base(logging)
{
_userService = userService;
}
[HttpGet]
[Route("api/users")]
public IList<UserDto> GetUsers()
{
try
{
return _userService.GetAllUsers();
}
catch (Exception e)
{
_logger.Error(e);
_logger.Trace(e);
throw;
}
}
[HttpPatch]
[Route("api/users/")]
public IHttpActionResult EditUsers(ICollection<UserEditDto> model)
{
try
{
_userService.EditUsers(model);
return Ok();
}
catch (Exception e)
{
_logger.Error(e);
_logger.Trace(e);
return BadRequest("Error");
}
}
}
Service layer:
public class UserService : IUserService
{
private readonly IServiceTools _serviceTools;
private readonly IUserQuerier _userQuerier;
public UserService(IServiceTools serviceTools, IUserQuerier userQuerier)
{
_serviceTools = serviceTools;
_userQuerier = userQuerier;
}
public void EditUsers(ICollection<UserEditDto> model)
{
var mapper = _serviceTools.AutoMapperConfiguration.Configure().CreateMapper();
var userEditCommands = mapper.Map<ICollection<UserEditDto>, ICollection<EditUserCommand>>(model);
foreach (var command in userSaveCommands)
{
_serviceTools.CommandBus.SendCommand(command);
CacheHelper.Clear(command.Id.ToString());
}
}
public IList<UserDto> GetAllUsers()
{
var allUsers = _userQuerier.GetAllUsers();
var result = allUsers.Select(x => new UserDto()
{
...
}).ToList();
return result;
}
}
Service Tools interface where command bus sits:
public interface IServiceTools
{
ICommandBus CommandBus { get; }
IAutoMapperConfiguration AutoMapperConfiguration { get; }
IIdentityProvider IdentityProvider { get; }
}
public class ServiceTools : IServiceTools
{
public ServiceTools(ICommandBus commandBus, IAutoMapperConfiguration autoMapperConfiguration, IIdentityProvider identityProvider)
{
CommandBus = commandBus;
AutoMapperConfiguration = autoMapperConfiguration;
IdentityProvider = identityProvider;
}
public ICommandBus CommandBus { get; }
public IAutoMapperConfiguration AutoMapperConfiguration { get; }
public IIdentityProvider IdentityProvider { get; }
}
And whatever handler for command:
public class EditUserHandler : IHandleCommand<EditUserCommand>
{
private readonly ICommandsContext _commandsContext;
public SaveUserHandler(ICommandsContext commandsContext)
{
_commandsContext = commandsContext;
}
public void Handle(EditUserCommand command)
{
... using dbcontext here...
}
}
}
For DI I use Autofac, all resources are set to per-request lifetime, split into modules, e.g. module for data access
public class DataModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<AppNameDbContext>().As<ICommandsContext>().InstancePerRequest();
builder.RegisterType<AppNameDbContext>().As<IQueryContext>().InstancePerRequest();
base.Load(builder);
}
}
The difference between both interfaces is that IQueryContext cannot change entity states and use SaveChagnes() method. IQueryContext have all DbSets in it, while ICommandsContext inherits from it and adds SettingState methods (added, modified, deleted) and SaveChanges() method.
IQueryContext is injected into queries and ICommandsContext into commands as seend in example aboove.
Now the Autofac config for command bus looks like that:
public class InfrastractureModule : Module
{
private ICommandsContext _commandsContext;
private ITranslationsCommandsContext _translationsCommandsContext;
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<AutoMapperConfiguration>().
As<IAutoMapperConfiguration>().InstancePerRequest();
builder.RegisterType<ServiceTools>().As<IServiceTools>().InstancePerRequest();
builder.Register(c =>
{
_commandsContext = c.Resolve<ICommandsContext>();
_translationsCommandsContext = c.Resolve<ITranslationsCommandsContext>();
return new CommandBus(CreateHandlersFactory);
})
.As<ICommandBus>().InstancePerRequest();
base.Load(builder);
}
private IHandleCommand CreateHandlersFactory(Type type)
{
if (type == typeof(XXXCommand))
{
return new XXXHandler(_commandsContext);
}
}
While the command bus looks like that
public class CommandBus : ICommandBus
{
private readonly Func<Type, IHandleCommand> _handlersFactory;
public CommandBus(Func<Type, IHandleCommand> handlersFactory)
{
_handlersFactory = handlersFactory;
}
public void SendCommand<T>(T command) where T : ICommand
{
var handler = (IHandleCommand<T>) _handlersFactory(typeof(T));
handler.Handle(command);
}
}
There is completely separate context used for translations for the app, but I do not thing that is important here.
I did not find any posts with similar problem. It only occurs when where two requests processed at the same time. I do not know if the configuration is wrong or Autofac messes things up, because it should not technically dispose dbcontext which was allocated for another request.
Sorry for the wall of text ;) I hope someone can help with that.
Obiously changing dbcontext's lifetime to SingleInstance fixed the problem, but we do not want that :)
SOLUTION EDIT:
As #ZeljkoVujaklija noticed CommandsDbContext declarations in InfrastractureModule seemed strange. I removed whole CommandBus registration from InfrastractureModule. Instead I created CommandsModule in the assembly where all the commands sit. It looks like that:
public class CommandsModule : Module
{
protected override void Load(ContainerBuilder builder)
{
base.Load(builder);
builder.RegisterAssemblyTypes(ThisAssembly)
.Where(x => x.IsAssignableTo<IHandleCommand>())
.AsImplementedInterfaces();
builder.Register<Func<Type, IHandleCommand>>(c =>
{
var ctx = c.Resolve<IComponentContext>();
return t =>
{
var handlerType = typeof(IHandleCommand<>).MakeGenericType(t);
return (IHandleCommand)ctx.Resolve(handlerType);
};
});
builder.RegisterType<CommandBus>()
.AsImplementedInterfaces();
}
}
Not only it fixes the problem but also gets rid of huge factory.
If you are running within ASP.NET Core you should run InstancePerLifetimeScope instead of InstancePerRequest
Use InstancePerLifetimeScope instead of InstancePerRequest. In previous ASP.NET integration you could register a dependency as InstancePerRequest which would ensure only one instance of the dependency would be created per HTTP request. This worked because Autofac was in charge of setting up the per-request lifetime scope. With the introduction of Microsoft.Extensions.DependencyInjection, the creation of per-request and other child lifetime scopes is now part of the conforming container provided by the framework, so all child lifetime scopes are treated equally - there’s no special “request level scope” anymore. Instead of registering your dependencies InstancePerRequest, use InstancePerLifetimeScope and you should get the same behavior. Note if you are creating your own lifetime scopes during web requests, you will get a new instance in these child scopes.
http://autofaccn.readthedocs.io/en/latest/integration/aspnetcore.html#differences-from-asp-net-classic
Is it good to resolve the dependencies dynamically like the way i'm doing. Everywhere, it is suggested to use Constructor injection. I really don't understand the drawbacks of doing it the way i'm doing it. Code snippets as below..
Employee.cs
public class Employee
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public Department Department { get; set; }
}
IRepository.cs
public interface IRepository<TModel> where TModel : class
{
void Add();
IEnumerable<TModel> GetAll();
IEnumerable<TModel> GetByID();
}
Repository.cs
public class Repository<TModel> : IRepository<TModel> where TModel : class
{
public void Add()
{
throw new NotImplementedException();
}
public IEnumerable<TModel> GetAll()
{
throw new NotImplementedException();
}
public IEnumerable<TModel> GetByID()
{
throw new NotImplementedException();
}
}
EmployeeController.cs
public class HomeController : ApiController
{
IComponentContext _container;
public HomeController(IComponentContext container)
{
this._container = container;
}
public Repository<TModel> Using<TModel>() where TModel :class
{
var repository = _container.Resolve(typeof(IRepository<TModel>));
return repository as Repository<TModel>;
}
[HttpGet]
public IEnumerable<Employee> GetEmployees()
{
return Using<Employee>().GetAll();
}
}
Global.asax
protected void Application_Start()
{
GlobalConfiguration.Configure(WebApiConfig.Register);
var builder = new ContainerBuilder();
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
builder.RegisterGeneric(typeof(Repository<>)).As(typeof(IRepository<>));
var container = builder.Build(Autofac.Builder.ContainerBuildOptions.None);
var webApiResolver = new AutofacWebApiDependencyResolver(container);
GlobalConfiguration.Configuration.DependencyResolver = webApiResolver;
}
Say i've 5 repositories, Constructor injection will resolve all the 5 dependencies for a request i make. I might not use 5 repositories for each and every request. SO i thought of resolving dependencies dynamically by passing the type like i'm doing it in Using<TModel>(). Any suggestions would be appreciated..!! Thank you...!!
Refrain from using the container directly inside your application components; this leads to all kinds of troubles such as maintainability and testability issues. Directly resolving instances from within application code is a well-known anti-pattern known as Service Locator.
As a first refactoring, you can instead apply the Unit of Work pattern. A Unit of Work allows access to underlying repositories. For instance:
public interface IUnitOfWork
{
IRepository<TModel> Repository<TModel>();
}
public sealed class HomeController : ApiController
{
private readonly IUnitOfWork _unitOfWork;
public HomeController(IUnitOfWork unitOfWork)
{
this._unitOfWork = unitOfWork;
}
[HttpGet]
public IEnumerable<Employee> GetEmployees()
{
return this._unitOfWork.Repository<Employee>().GetAll();
}
}
Within the Composition Root (where it is allowed to access the container), we can now create an IUnitOfWork implementation that resolves repositories dynamically:
private sealed class AutofacUnitOfWork : IUnitOfWork
{
private readonly IComponentContext _container;
public AutofacUnitOfWork(IComponentContext container)
{
this._container = container;
}
public IRepository<TModel> Repository<TModel>()
{
return _container.Resolve<IRepository<TModel>>();
}
}
This pattern simplifies your application components considerably and prevents downsides that the Service Locator anti-pattern typically causes.
Although applying the Unit of Work pattern might be a useful step into the right direction, an even better approach is to skip the Unit of Work directly and simply inject a required repository directly into application components:
public sealed class HomeController : ApiController
{
private readonly IRepository<Employee> _employeeRepository;
public HomeController(IRepository<Employee> employeeRepository)
{
this._employeeRepository = employeeRepository;
}
[HttpGet]
public IEnumerable<Employee> GetEmployees()
{
return this._employeeRepository.GetAll();
}
}
Say i've 5 repositories, Constructor injection will resolve all the 5 dependencies for a request i make. I might not use 5 repositories for each and every request.
Note that from a performance perspective, you should typically not be concerned whether dependencies are used or not. Autofac is in most cases fast enough and it is unlikely that this will actually cause any performance problems in your production systems.
From a design perspective however you should be more worried if a class has many dependencies, while methods just use a few of them. This means that the methods in the class have little cohesion. This is an indication that the class should be split up into multiple smaller classes; it has multiple responsibilities.
I'm trying to inject a service using the IoC container into a Validation class. See the example below:
[Validator(typeof(UserPayloadValidator))]
public class UserPayload
{
public int UserId { get; set; }
}
public class UserPayloadValidator : AbstractValidator<UserPayload>
{
private IUserService _userService;
public UserPayloadValidator(IUserService userService)
{
_userService = userService;
RuleFor(x => x.UserId).Must(BeUnique).WithMessage("This user already exists");
}
private bool BeUnique(int userId)
{
var user = _userService.GetUser(userId);
return user == null;
}
}
At this point I was hoping everything would auto-magically work and the userService would be injected into the validation class. Instead, I get an exception complaining about a parameter-less constructor not being found.
After some reasearch I've attempted to create a ValidationFactory as in the example linked.
public class LightInjectValidationFactory : ValidatorFactoryBase
{
private readonly ServiceContainer _serviceContainer;
public LightInjectValidationFactory(ServiceContainer serviceContainer)
{
_serviceContainer = serviceContainer;
}
public override IValidator CreateInstance(Type validatorType)
{
return _serviceContainer.TryGetInstance(validatorType) as IValidator;
}
}
and in the LightInject configuration
//Set up fluent validation
FluentValidationModelValidatorProvider.Configure(httpConfiguration, provider =>
{
provider.ValidatorFactory = new LightInjectValidationFactory(container);
});
This results in an exception:
Unable to resolve type: FluentValidation.IValidator`1
I guess the IoC container doesn't know how to resolve the correct instance for the validator.
Any ideas are much appreciated.
Thanks to the comment above I realized I wasn't actually registering the validator in container. This can be done like this for all the validators:
FluentValidation.AssemblyScanner.FindValidatorsInAssemblyContaining<UserPayloadValidator>()
.ForEach(result =>
{
container.Register(result.InterfaceType, result.ValidatorType);
});
Please note that UserPayloadValidator needs to be just one of your validators. Based on this type, FindValidatorsInAssembly can infer all the other available validators.
Also, in the validation factory you should use TryGetInstance instead of GetInstance in case the factory tries to instantiate non existant validators (parameter in the controller for which validators do not exist)
I have found solution for all validation classes use injected service.
Replace below code
FluentValidation.AssemblyScanner.FindValidatorsInAssemblyContaining<UserPayloadValidator>()
.ForEach(result =>
{
container.Register(result.InterfaceType, result.ValidatorType);
});
With
FluentValidation.AssemblyScanner findValidatorsInAssembly = FluentValidation.AssemblyScanner.FindValidatorsInAssembly(typeof(UserPayloadValidator).Assembly);
foreach (FluentValidation.AssemblyScanner.AssemblyScanResult item in findValidatorsInAssembly)
{
container.Register(item.InterfaceType, item.ValidatorType);
}
Using this your all validator classes use injected service.
This question already has an answer here:
How to implement a UserFactory using IHttpContextAccessor
(1 answer)
Closed 4 years ago.
I am trying to recreate HttpContext.Current in vNext but I am having trouble with this.
The code so far:
public class CurrentContext
{
public IHttpContextAccessor ctx { get; private set; }
public CurrentContext(IHttpContextAccessor accessor)
{
ctx = accessor;
}
}
services.AddTransient<CurrentContext>();
I want to use:
public static class UserFactory
{
public static void SetCurrentUser(User u)
{
//tryed to get the context but GetService returns null
IHttpContextAccessor _context = ((CurrentContext)CallContextServiceLocator.Locator.ServiceProvider.GetService(serviceType: typeof(CurrentContext))).ctx;
//add the user to the Session
}
}
How can I now get an instance of CurrentContext anywhere in the project?
I do not use the vNext DI system, but I believe you should define an interface for your CurrentContext, e.g.
public interface IContextProvider {
IHttpContextAccessor GetContext();
}
And then use
public class CurrentContextProvider : IContextProvider
{
private readonly IHttpContextAccessor _context;
public CurrentContextProvider(IHttpContextAccessor accessor)
{
_context = accessor;
}
public IHttpContextAccessor GetContext() {
return _context;
}
}
And wire
services.AddScoped<IContextProvider, CurrentContextProvider>();
But if you are going to just use the context, why dont just depend directly on the IHttpContextAccessor - where you need it?
You should declare the variable of the CurrentContext type in constructors of dependent classes:
public class SomeClassThatUsesCurrentContext
{
private readonly SomeClassThatUsesCurrentContext currentContext;
public SomeClassThatUsesCurrentContext(CurrentContext currentContext)
{
if (currentContext == null)
throw new ArgumentNullException("currentContext");
this.currentContext = currentContext;
}
}
These classes may occur in constructors of other classes. Finally you usually resolve from the DI container the single instance of the high level class. The place where you do it is called composite root.
And, as #janhartmann says, usually you should use interfaces or abstract classes instead of concrete classes.