Dears,
I used Automapper IMappingAction to encapsulate Before and After Map Actions into small reusable classes but i can't make my class work with ASPNET Bolierplate Ioc Castle Windsor
configuration.CreateMap<CustomerDto, Customer>()
.AfterMap<CustomerAction>().ReverseMap();
public class CustomerAction : IMappingAction<CustomerDto, Customer>
{
private readonly IObjectMapper _objectMapper;
public CustomerAction(IObjectMapper objectMapper)
{
_objectMapper = objectMapper;
}
public void Process(CustomerDto customerDto, Customer customer)
{
}
}
when my code get execute, i got exception that my class doesn't have parameterless constructor
https://github.com/aspnetzero/aspnet-zero-core/issues/1587#issuecomment-415617774
Do you try this?
cfg.CreateMap<CustomerDto, Customer>().AfterMap((source, destination) =>
{
var action = IocManager.IocContainer.Resolve<CustomerAction>();
action.Process(source, destination);
}).ReverseMap();
public class CustomerAction : IMappingAction<CustomerDto, Customer>, ITransientDependency
{
private readonly IObjectMapper _objectMapper;
public CustomerAction(IObjectMapper objectMapper)
{
_objectMapper = objectMapper;
}
public void Process(CustomerDto customerDto, Customer customer)
{
}
}
Related
I have Core in which Interface is declared as
public interface IRequestProvider
{
int SomeId { get; set; }
}
Implementation also define in same layer
and then I have another layer Repo layer in which I am calling another external nuget packages called DataAccess layer
in which I have declared
public interface IRequestProvider
{
int SomeId { get; set; }
int SomeOtherId { get; set; }
}
so In core and DataAccess both layer I have defined IRequestProvider
Lamar code
public static class SomeRegistry
{
public static void RegisterDISome(this ServiceRegistry services, IConfigurationRoot configurationRoot)
{
services.For<IRequestProvider>().Use<RequestProvider>().Scoped();
services.For<DataAccessInterfaces.IRequestProvider>().Use<DataAccessModel.RequestProvider>().Scoped();
}
}
Scoped use to pass the same instance throughout the request
Automapper is enable
public class DomainToRepoMappingsProfile : Profile
{
public DomainToRepoMappingsProfile()
{
this.CreateMap<IRequestProvider, DataAccess.IRequestProvider>()
.ForMember(dst => dst.SomeOtherId, opt => opt.Ignore());
}
}
My expectation is when I change something in Core.IRequestProvider from any layer it should auto reflected in DataAccess.IRequestProvider layer
Currently I am calling IDomainToRepoMappingRequestProvider.map() each time to set DataAccess.IRequestProvider
public class DomainToRepoMappingRequestProvider : IDomainToRepoMappingRequestProvider
{
private readonly IMapper _mapper = null;
private readonly IRequestProvider _requestProvider = null;
private DataAccess.IRequestProvider _dataAccessRequestProvider = null;
public DomainToRepoMappingRequestProvider(IRequestProvider requestProvider, DataAccess.IRequestProvider dataAccessRequestProvider, IMapper mapper)
{
_mapper = mapper;
_requestProvider = requestProvider;
_dataAccessRequestProvider = dataAccessRequestProvider;
}
public void Map()
{
_mapper.Map(_requestProvider, _dataAccessRequestProvider);
}
}
I finding a solution to reflect changes automatically when something is changed without calling map()
How about having a property setter in the implementation of IRequestProvider call the mapper for you? The property getters and setters can be used to do much more than just setting a private backing field. An example:
public class RequestProvider : IRequestProvider
{
private readonly _mappingProvider;
private int _someId;
public RequestProvider(IDomainToRepoMappingRequestProvider mappingProvider)
{
_mappingProvider = mappingProvider
}
public int SomeId
{
get;
set
{
_someId = value;
_mappingProvider.Map();
}
}
}
I'm using CQRS pattern in my recent project, and used EF code first in my DAL, so I defined some generic CommandHandlers to do Insert/Update/Delete:
public class InsertCommandHandler<TEntity> : ICommandHandler<InsertCommandParameter<TEntity>>
where TEntity : BaseEntity, IAggregateRoot<TEntity>, new()
{
private readonly IUnitOfWork _uow;
public InsertCommandHandler(IUnitOfWork uow)
{
_uow = uow;
}
public void Handle(InsertCommandParameter<TEntity> parameter)
{
var entity = parameter.Entity;
_uow.Repository<TEntity>().Add(entity);
}
}
public interface ICommandParameter
{
}
public abstract class BaseEntityCommandParameter<T> : ICommandParameter
where T : BaseEntity, new()
{
public T Entity { get; set; }
protected BaseEntityCommandParameter()
{
Entity = new T();
}
}
public class InsertCommandParameter<T> : BaseEntityCommandParameter<T> where T : class, new()
{
}
As you see I injected the IUnitOfWork to the InsertCommandHandler constructor.
public interface IUnitOfWork : IDisposable
{
IRepository<T> Repository<T>() where T : BaseEntity, IAggregateRoot<T>,new ();
void Commit();
}
I used Structuremap 3 as my IoC Container, So I defined following conversion to resolve ICommandHandlers for each BaseEntity types(using custom registration conventions for partially closed types):
public class CRUDCommandRegistrationConvention : StructureMap.Graph.IRegistrationConvention
{
private static readonly
Type _openHandlerInterfaceType = typeof(ICommandHandler<>);
private static readonly
Type _openInsertCommandType = typeof(InsertCommandParameter<>);
private static readonly
Type _openInsertCommandHandlerType = typeof(InsertCommandHandler<>);
private static readonly
Type _openUpdateCommandType = typeof(UpdateCommandParameter<>);
private static readonly
Type _openUpdateCommandHandlerType = typeof(UpdateCommandHandler<>);
private static readonly
Type _openDeleteCommandType = typeof(DeleteCommandParameter<>);
private static readonly
Type _openDeleteCommandHandlerType = typeof(DeleteCommandHandler<>);
public void Process(Type type, Registry registry)
{
if (!type.IsAbstract && typeof(BaseEntity).IsAssignableFrom(type))
if (type.GetInterfaces()
.Any(x => x.IsGenericType && x.GetGenericTypeDefinition()
== typeof(IAggregateRoot<>)))
{
Type closedInsertCommandType = _openInsertCommandType.MakeGenericType(type);
Type closedInsertCommandHandlerType = _openInsertCommandHandlerType.MakeGenericType(type);
Type closedUpdateCommandType = _openUpdateCommandType.MakeGenericType(type);
Type closedUpdateCommandHandlerType = _openUpdateCommandHandlerType.MakeGenericType(type);
Type closedDeleteCommandType = _openDeleteCommandType.MakeGenericType(type);
Type closedDeleteCommandHandlerType = _openDeleteCommandHandlerType.MakeGenericType(type);
Type insertclosedHandlerInterfaceType = _openHandlerInterfaceType.MakeGenericType(closedInsertCommandType);
Type updateclosedHandlerInterfaceType = _openHandlerInterfaceType.MakeGenericType(closedUpdateCommandType);
Type deleteclosedHandlerInterfaceType = _openHandlerInterfaceType.MakeGenericType(closedDeleteCommandType);
registry.For(insertclosedHandlerInterfaceType).Use(closedInsertCommandHandlerType);
registry.For(updateclosedHandlerInterfaceType).Use(closedUpdateCommandHandlerType);
registry.For(deleteclosedHandlerInterfaceType).Use(closedDeleteCommandHandlerType);
}
}
}
And used it in my CompositionRoot:
public static class ApplicationConfiguration
{
public static IContainer Initialize()
{
ObjectFactory.Initialize(x =>
{
x.Scan(s =>
{
s.AssemblyContainingType(typeof(ICommandHandler<>));
s.AssemblyContainingType(typeof(Order));
s.AssemblyContainingType(typeof(FindOrderByIdQueryHandler));
s.WithDefaultConventions();
x.For(typeof(IUnitOfWork))
.Use(typeof(EfUnitOfWork<SaleDBContext>))
.Named("SaleDBContext")
.SetLifecycleTo((Lifecycles.Singleton));
s.Convention<CRUDCommandRegistrationConvention>();
});
});
return ObjectFactory.Container;
}
public static T Resolve<T>()
{
return ObjectFactory.GetInstance<T>();
}
}
I registered EfUnitOfWork<SaleDBContext> for IUnitOfWork, but I want to use separate DbContext per each module in my solution(Bounded context). For example my sale module has its own DbContext, HR module has its own DbContext and etc, and above registration conversion, only register EfUnitOfWork<SaleDBContext> as my IUnitOfWork.
I have some modules(Solution Folders in Visual Studio) in my solution and each module has 3 layer(3 class library projects):
My modules has following structure(each module has 3 assemblies) for example:
SaleModule:
----Application
----Domain (Entities , ...) //Order, Customer,...
----DAL (DbContext ,...) //SaleDbContext
HRModule:
----Application
----Domain (Entities , ...) // Employee, OrganizationUnit, ...
----DAL (DbContext ,...)//HRDbContext
InfrastructureModule:
----Application (ICommandHandler,IQueryHandler,...)
----Domain
----DAL
The InsertCommandHandler<T> puts in Infrastructure Module.
When I use the InsertCommanHandler<T> I want it uses corresponding module's DbContext as IUnitOfWork. for example, I want the InsertCommandHandler<Order> uses SaleDbContext as it's IUnitOfWork and InsertCommandHandler<Employee> uses HRDbContext as it's IUnitOfWork.
[UPDATED]
This is a sample of cunsumers code that IoC containar should provide SaleDbContext for Consumer1 and HRDbContext for Consumer2:
public class Consumer1
{
ICommandHandler<InsertCommandParameter<Order>> _insertCommandHandler;
public Consumer1(ICommandHandler<InsertCommandParameter<Order>> insertCommandHandler)
{
_insertCommandHandler = insertCommandHandler;
}
public void DoInsert()
{
var command = new InsertCommandParameter<Order>();
command.Entity = new Order(){
Number = 'ord-01',
// other properties
};
insertCommandHandler.Handle(command); //this query handler should use SaleDbContext
}
}
public class Consumer2
{
ICommandHandler<InsertCommandParameter<Employee>> _insertCommandHandler;
public Consumer2(ICommandHandler<InsertCommandParameter<Employee>> insertCommandHandler)
{
_insertCommandHandler = insertCommandHandler;
}
public void DoInsert()
{
var command = new InsertCommandParameter<Employee>();
command.Entity = new Employee(){
EmployeeNumber = 'Emp1',
// other properties
};
insertCommandHandler.Handle(command); //this query handler should use HRDbContext
}
}
How could I do that in my composition root using StructureMap?
You can make IUnitOfWork generic as in IUnitOfWork<TConnection>. This allows each Repository to stipulate which UnitOfWork it requires, ideally using constructor injection, e.g.
public class InsertCommandHandler : ICommandHandler<Order>
{
public InsertCommandHandler(IUnitOfWork<SalesDbContext> salesUnitOfWork)
{
// ...
}
}
However, you probably don't want to reference the DbContext in each handler so you should define an abstraction to avoid such a dependency.
Start with a simple interface that all DbContext wrapper classes will implement
public interface IConnection
{
DbContext Context { get; }
}
Update IUnitOfWork accordingly
public interface IUnitOfWork<TConnection> where TConnection : IConnection { }
Here's an example wrapper
public class SalesConnection : IConnection
{
private readonly DbContext context;
public SalesConnection()
{
this.context = new SalesDbContext();
}
public DbContext Context { get { return this.context; } }
}
And here's what the updated command handler will look like
public class InsertCommandHandler : ICommandHandler<Order>
{
public InsertCommandHandler(IUnitOfWork<SalesConnection> salesUnitOfWork)
{
// ...
}
}
UPDATE
The logical thing to do for common handlers is to have one per logical domain (i.e. per DbContext), for example SalesInsertCommandHandler, HRInsertCommandHandler
public class SalesInsertCommandHandler<TCommand> : ICommandHandler<TCommand>
{
public SalesInsertCommandHandler(IUnitOfWork<SalesConnection> unitOfWork)
{
}
}
This adheres to the separation of concerns principle and gives you extra flexibility when you come to decorate your concerns with different aspects (tracing, retry logic etc.)
All command handlers can of course inherit from a single common (abstract) command handler.
public abstract class CommandHandler<TConnection, TCommand> :
ICommandHandler<TCommand>
where TConnection : IConnection
{
private readonly IUnitOfWork<TConnection> unitOfWork;
public CommandHandler(IUnitOfWork<TConnection> unitOfWork)
{
this.unitOfWork = unitOfWork;
}
}
public class SalesInsertCommandHandler<TCommand> :
CommandHandler<SalesConnection, TCommand>
{
}
I am wondering how to deal with a situation when inside one service lets say ICompanyService I need to call another method from IUserAccountService. ?
So generally lets say that a Company shouldn't exist without an UserAccount.
The IUserAccount implementation service class looks like this:
public class UserAccountService : CrudService<UserAccount>, IUserAccountService
{
private readonly IRepository<UserAccount> _userAccountRepository;
private readonly IUnitOfWorkFactory _unitOfWorkFactory;
public CompanyService(IRepository<UserAccount> userAccountRepository,
IUnitOfWorkFactory unitOfWorkFactory)
: base(userAccountRepository, unitOfWorkFactory)
{
_userAccRepository = userAccRepository;
}
public int RegisterUser(UserAccount user) {
using (var uow=_unitOfWorkFactory.Create())
{
// Details omitted for brievity
var userId = _userAccountRepository.Create(user);
uow.Commit();
return userId;
}
}
//Other service methods
}
The company ICompanyService implementation:
public class CompanyService : CrudService<Company>, ICompanyService
{
private readonly IRepository<Company> _companyRepository;
private readonly IUnitOfWorkFactory _unitOfWorkFactory;
public CompanyService(IRepository<Company> companyRepository,
IUnitOfWorkFactory unitOfWorkFactory)
: base(companyRepository, unitOfWorkFactory)
{
_companyRepository= companyRepository;
}
public int CreateCompanyWithUserAccount(Company company) {
using (var uow=_unitOfWorkFactory.Create())
{
// Some validation with the company.Details omitted for brievity
// Here I need an instance of IUserAccountService
// Suppose I get it through DI or IoC
var userAccountService = IoC.Resolve<IUserAccountService>();
### // Is such approach good or bad?! ###
var userId = userAccountService.RegisterUser(company.UserAccount);
// Map the user id to the company
company.UserAccount.Id = userId;
var companyId = _companyRepository.Create(company);
uow.Commit();
return companyId;
}
}
//Other service methods
}
ORM under the repository is: NHibernate
Seems you have wrong constructor in UserAccountService implementations: public CompanyService
In CompanyService implementation, you better resolve IUserAccountService dependency right in a constructor, so you do it once per object creation, not each time you call method.
There's no problems with those dependencies. If two objects of IUnitOfWorkFactory implementations are problem -> make a singleton
You could just take a dependency on the IRepository<UserAccount>:
public class CompanyService : CrudService<Company>, ICompanyService
{
private readonly IRepository<Company> _companyRepository;
private readonly IRepository<UserAccount> _userAccountRepository;
private readonly IUnitOfWorkFactory _unitOfWorkFactory;
public CompanyService(IRepository<Company> companyRepository,
IUnitOfWorkFactory unitOfWorkFactory
IRepository<UserAccount> userAccountRepository)
: base(companyRepository, unitOfWorkFactory)
{
_companyRepository= companyRepository;
_userAccountRepository = userAccountRepository;
}
public int CreateCompanyWithUserAccount(Company company) {
using (var uow=_unitOfWorkFactory.Create())
{
// Some validation with the company.Details omitted for brievity
var userId = _userAccountRepository.Create(company.UserAccount);
// Map the user id to the company
company.UserAccount.Id = userId;
var companyId = _companyRepository.Create(company);
uow.Commit();
return companyId;
}
}
//Other service methods
}
IMO, it's better to take a dependency on the repository. After all your company service is creating a company and it needs to do some work in the database, which is what the repositories are for. From what I can see in the code, there's no need to involve the UserAccountService.
What is the best way to handle a situation where you're using IoC but there is a static method in it along with the other methods like the following:
public partial class ShoppingCart
{
private IDatabaseFactory _storeDB;
public ShoppingCart(IDatabaseFactory storeDB)
{
_storeDB = storeDB;
}
private string ShoppingCartId { get; set; }
public static ShoppingCart GetCart(HttpContextBase context)
{
var cart = new ShoppingCart(WHATGOESHERE?);
cart.ShoppingCartId = cart.GetCartId(context);
return cart;
}
public int OtherMethod()
{
...
}
}
The static GetCart method is an Ambient Context. It's a bad idea, especially to have such a method at the level of your domain model. Try refactoring it to an abstract factory:
public interface IShoppingCartFactory
{
ShoppingCart GetCartForCurrentUser();
}
You can inject the IShoppingCartFactory in services that need it (but not in your entities, it's better to keep your entities clean). Now you can define an implementation and register it in your IoC configuration. Here's an example of such an implementation:
public class HttpShoppingCartFactory : IShoppingCartFactory
{
private readonly IShoppingUnitOfWorkFactory uowFactory;
public HttpShoppingCartFactory(
IShoppingUnitOfWorkFactory uowFactory)
{
this.uowFactory = uowFactory;
}
public ShoppingCart GetCartForCurrentUser()
{
int userId = (int)HttpContext.Current.Session["userId"];
using (var unitOfWork = this.uowFactory.CreateNew())
{
return unitOfWork.ShoppingCards
.FirstOrDefault(c => c.User.Id == userId);
}
}
}
It would be even better to separate the getting the user context from the shopping card factory. For instance, you yould inject a IUserContextFactory in the shopping card factory, making it independant on ASP.NET.
IMO you should refactor it, making it to look like this:
public class ShoppingCartService {
private readonly IDatabaseFactory _storeDB;
public ShoppingCartService(IDatabaseFactory storeDB) {
_storeDB = storeDB
}
public ShoppingCart GetCart(IdType cartId)
{
var cart = new ShoppingCart(_storeDB);
cart.ShoppingCartId = cartId;
return cart;
}
}
public partial class ShoppingCart
{
private IDatabaseFactory _storeDB;
public ShoppingCart(IDatabaseFactory storeDB)
{
_storeDB = storeDB;
}
private string ShoppingCartId { get; set; }
public int OtherMethod()
{
...
}
}
This way, you are moving responsibility to get the current shopping cart from a static method to a service class you can inject in the presentation layer.
I'm using FluentValidation 2 for validating some entities. I'd like to create an IValidationService that I can pass into other services to allow them to perform validation. I'd like to expose it like this:
public interface IValidationEngine
{
IEnumerable<ValidationError> Validate<T>(T entity);
}
Where ValidationError is a class that encapsulates my validation errors. Ideally, I'd like to not have to expose a specific validator to one of my services (such as OrderValidator). I'd like the validation service be capable of constructing/finding the correct validator. Does FV have anything built in for locating a validator for a specific type (and it internally caches)? Or, do I have to go the IValidatorFactory route and then wire each validator with my IoC container?
I've managed to solve this with the IValidatorFactory method. I'm using Ninject, so specific IoC details below would need to be changed.
public interface IValidationService
{
IEnumerable<ValidationError> Validate<T>(T entity)
where T : class;
}
public class FluentValidationService : IValidationService
{
private readonly IValidatorFactory validatorFactory;
public FluentValidationService(IValidatorFactory validatorFactory)
{
this.validatorFactory = validatorFactory;
}
public IEnumerable<ValidationError> Validate<T>(T entity)
where T : class
{
var validator = this.validatorFactory.GetValidator<T>();
var result = validator.Validate(entity);
return result.Errors.Select(e => new ValidationError(e.PropertyName, e.ErrorMessage));
}
}
// Then implement FV's IValidatorFactory:
public class NinjectValidatorFactory : ValidatorFactoryBase
{
private readonly IKernel kernel;
public NinjectValidatorFactory(IKernel kernel)
{
this.kernel = kernel;
}
public override IValidator CreateInstance(Type validatorType)
{
return kernel.TryGet(validatorType) as IValidator;
}
}
// I then wire both of these in a Ninject Module:
public class ValidationModule : NinjectModule
{
public override void Load()
{
this.Bind<IValidationService>().To<FluentValidationService>().InRequestScope(); // Specific to MVC.
this.Bind<IValidatorFactory>().To<NinjectValidatorFactory>().InRequestScope();
}
}
// Then I can use it inside a service:
public class FooService
{
private readonly IValidationService validationService;
public FooService(IValidationService validationService)
{
this.validationService = validationService;
}
public bool Add(Foo foo)
{
if(this.validationService.Validate(foo).Any())
{
// Handle validation errors..
}
// do other implementation details here.
}
}