I have been playing around the last couple of days with different solutions for mapping DTO's to entities for a VS2013, EF6, WCF Service App project.
It is a fairly large project that is currently undergoing a major refactoring to bring the legacy code under test (as well as port the ORM from OpenAccess to EF6).
To be honest I had never used AutoMapper before but what I saw I really liked so I set out to test it out in a demo app and to be honest I am a bit ashamed that I have been unable to achieve a working solution after hours of tinkering and Googling. Here is a breakdown of the project:
WCF Service Application template based project (.svc file w/code behind).
Using Unity 3.x for my IoC container and thus creating my own ServiceHostFactory inheriting from UnityServiceHostFactory.
Using current AutoMapper nuget package.
DTO's and DAL are in two separate libraries as expected, both of which are referenced by the service app project.
My goal is simple (I think): Wire up and create all of my maps in my composition root and inject the necessary objects (using my DI container) into the class that has domain knowledge of the DTO's and a reference to my DAL library. Anyone that needs a transformation would therefore only need to reference the transformation library.
The problem: Well, there are a couple of them...
1) I cannot find a working example of AutoMapper in Unity anywhere. The code snippet that is referenced many times across the web for registering AutoMapper in Unity (see below) references a Configuration class that doesn't seem to exist anymore and I cannot find any documentation on its deprecation:
container.RegisterType<AutoMapper.Configuration, AutoMapper.Configuration>(new PerThreadLifetimeManager(), new InjectionConstructor(typeof(ITypeMapFactory),
AutoMapper.Mappers.MapperRegistry.AllMappers())).RegisterType<ITypeMapFactory,
TypeMapFactoy>().RegisterType<IConfiguration, AutoMapper.Configuration>().RegisterType<IConfigurationProvider,
AutoMapper.Configuration>().RegisterType<IMappingEngine, MappingEngine>();
2) Where to create the maps themselves... I would assuming that I could perform this operation right in my ServiceHostFactory but is that the correct place? There is a Bootstrapper project out there but I have not gone down that road (yet) and would like to avoid it if possible.
3) Other than the obviously necessary reference to AutoMapper in the DTO lib, what would I be injecting into the instantition, the configuration object (assuming IConfiguration or IConfigurationProvider) and which class I am injecting into the constructor of the WCF service to gain access to the necessary object.
I know #3 is a little vague but since I cannot get AutoMapper bound in my Unity container, I cannot test/trial/error to figure out the other issues.
Any pointers would be greatly appreciated.
UPDATE
So I now have a working solution that is testing correctly but would still like to get confirmation that I am following any established best practices.
First off, the Unity container registration for AutoMapper (as of 11/13/2013) v3.x looks like this:
container
.RegisterType<ConfigurationStore, ConfigurationStore>
(
new ContainerControlledLifetimeManager()
, new InjectionConstructor(typeof(ITypeMapFactory)
, MapperRegistry.AllMappers())
)
.RegisterType<IConfigurationProvider, ConfigurationStore>()
.RegisterType<IConfiguration, ConfigurationStore>()
.RegisterType<IMappingEngine, MappingEngine>()
.RegisterType<ITypeMapFactory, TypeMapFactory>();
Right after all of my container registrations, I created and am calling a RegisterMaps() method inside of ConfigureContainer(). I created a test mapping that does both an auto mapping for like named properties as well as a custom mapping. I did this in my demo app for two reasons primarily:
I don't yet know AutoMapper in a WCF app hosted in IIS and injected with Unity well enough to fully understand its behavior. I do not seem to have to inject any kind of configuration object into my library that does the transformations and I am still reading through the source to understand its implementation.
As I understand it, there is a caching mechanism at play here and that if a mapping is not found in cache that it will create it on the fly. While this is great in theory, the only way I could then test my mappings that were occurring in my composition root was to do some sort of custom mapping and then call Mapper.Map in the library that performs mapping and returns the DTO.
All of that blathering aside, here is what I was able to accomplish.
WCF Service App (composition root) injects all of the necessary objects including my DtoConversionMapper instance.
The project is made up of the WCF Service App (comp root), DtoLib, DalLib, ContractsLib (interfaces).
In my ServiceFactoryHost I am able to create mappings, including custom mappings (i.e. map unlike named properties between my DTO and EF 6 entity).
The DtoConversionMapper class lives in the DtoLib library and looks like this: IExampleDto GetExampleDto(ExampleEntity entity);
Any library with a reference to the DtoLib can convert back and forth, including the Service App where the vast majority of these calls will take place.
Any guiding advice would be greatly appreciated but I do have a working demo now that I can test things out with while I work through this large refactoring.
Final Update
I changed the demo project just a little by adding another library (MappingLib) and moved all of my DTO conversions and mappings to it in a static method. While I still call the static method in my composition root after the Unity container is initialized, this gives me the added flexibility of being able to call that same map creation method in my NUnit unit test libraries, effectively eliminating any duplication of code surrounding auto mapper and makes it very testable.
Related
This question already has answers here:
Ioc/DI - Why do I have to reference all layers/assemblies in application's entry point?
(4 answers)
Closed 3 years ago.
My application includes the Presentation Layer Project which is the Web-server's project.
In the Startup class of the PL I add a singleton service of type IServiceFacade. The controllers will be injected with it and use it to speak with the lower Service Layer Project functionality (PL Project holds a reference to the ServiceLayer Project).
The ServiceFacade holds an object of type IBusinessLogicFacade and uses it to speak with the lower Business Layer Project (Service Layer Project holds a reference to the Business Logic Project).
I also use the .net Core built-in logging API to inject ILogger to the controllers, the ServiceFacade and the BusinessLogicFacade, this only requires a reference to Microsoft.Extensions.Logging.
Like I added the ServiceFacade as a service, thus enabling the injection,
I would like to add the BusinessLogicFacade as a service, But this will require a reference from the PL Project to the Business Logic Project, breaking the layer separation.
I could create the BusinessLogicFacade "manually" in the ServiceFacade, but I will then need to supply an ILogger too, because I cannot use the injection of it when creating the BusinessLogicFacade manually.
services.AddSingleton<IServiceFacade,ServiceFacade> (OK, PL holds a reference to ServiceLayer Project)
services.AddSingleton<IBusinessLogicFacade,BusinessLogicFacade> (Not OK, Requires a reference from PL to BL).
Is there a way to receive the some parameters (as the ILogger) through injection when "manually" creating an object?
How should I approach this problem?
Unfortunately, this (dependency reference) is not straightforward to avoid - especially when using the default ASP.Net core container. You could work around this issue using 3rd party DI containers. You can read about architecture ideas here. Specifically for your question, read the "Note" section in the "UI layer types" paragraph (after Figure 5.12 in the specified link).
We have many projects based on the provider model/pattern. (Reading files from various sources, create reports from various sources, etc.) I have been unable to find anything equivalent to the ProviderBase in .net 5. We need an abstract interface/class that can be configured at runtime.
I suspect ProviderBase is something we will never see in ASP.NET 5 and beyond. Configuration is simpler in 5, and dependency injection is prevalent. Now you can create a class implementing your own custom interface and not have forced inheritance from ProviderBase. You can register the class or an instance of the class with a container and it will appear throughout the application. It might look like a bit more work at first, but I also suspect embracing DI will result in less code, and simpler code.
In NopCommerece MVC version, I am trying to move the mapping folder out of the DAL project to a seperate class library project, I am trying it to make the DAL more generic, so that it can be used in other projects as well.
But when I run the application, for every entity it says that "The entity type [EntityName] is not part of the model for the current context."
I think its happening because autofac is not finding IRepository for injection, any tips or ideas that where and what I am doing wrong?
Thanks in advance
OK! I found the solution to this issue, in the ObjectContext file, there is an overridden method named OnModelCreating, which was basically creating instances of mapping type objects in the assembly through reflection.
I have asked this method to look into a specific dll for those mapping entries and it started working.
I've designed my classes using CRC cards and I have a lovely set of objects that contain domain/business logic AND data (properties). Some of the classes require saving to and reading from a database.
My repository should exist in a separate project to my domain objects, but needs to reference them in order to create them.
However, the domain objects/entities need to be able to reference the repository.
I could put the objects in the repository, but as they contain domain functionality, that doesn't feel right at all.
I could put the objects that require persistence in a common shared project, but again it feels wrong to single them out.
Where should I put them? I cant help feeling I'm missing something obvious.
Domain objects/entities should not use repositories. Its domain/applications services should use repositories. And that's done very simple - you should define repository interfaces in your Domain Model assembly and use them in domain/application services.
Domain library should contain
Domain Model
Repository Interfaces
Domain Services (use only interfaces of repositories)
This library does not reference other libraries - it sits at the core of your system.
Persistence library should contain implementation of repositories specific to your data provider. E.g. it can use Entity Framework. This library should reference your domain library. Thus it will know about interfaces it should implement and about entities it should work with.
However, the domain objects/entities need to be able to reference the repository.
Do they? Or do they need to reference the interface of the repository? Then the repository itself is just an implementation of that interface, a low-level detail not needed by the domain logic code.
The way I normally structure a repository pattern in my projects is:
Domain Core Project (business models, core business logic, interfaces for dependencies)
Dependency Projects (references Domain Core Project, implements interfaces)
Application Projects (references Domain Core Project, references Dependency Projects either directly, or through configuration, or through an intermediary project which handles dependency injection)
As an example, suppose I'm using a Service Locator for my dependency injection (which I very often do). Then the business models only need to reference the Service Locator object (which itself is supplied by a factory and can be injected). So internal to a business model I might have something like this:
public class SomeBusinessModel
{
private ISomeDependency SomeProperty
{
get
{
return DIFactory.Current.Resolve<ISomeDependency>();
}
}
}
The DIFactory has a static property called Current which is basically a factory method returning a dependency injection resolver, and its interface has a method called Resolve which takes a type and returns an instance.
So in this case...
SomeBusinessModel is in the Domain Core Project
ISomeDependency is in the Domain Core Project
IDIContainer (the return type for Current) is in the Domain Core Project
DIFactory is in the Domain Core Project, and is initialized (it has an Initialize method that sets the current injection container) by the Application Project for a specific dependency injection container
SomeDependency (the actual instance type being returned by the resolver) is in a Dependency Project
In this setup, the business models know that there needs to be a repository, and require that one be supplied, but they don't have a hard dependency on them. The application supplies the actual implementations for those repositories, either directly by providing an instance or indirectly by configuring a dependency injection container to provide an instance.
All actual dependencies point inward from the implementation details (applications and dependencies) to the core business logic. Never outward.
I want to use Ninject 2 on Castle Monorail. Searching on google, I found nothing about this.
I know there is Windsor which magically can integrate with Monorail, same as Ninject (with MVC extension) with ASP.NET MVC.
What steps I need to do to integrate DI framework (other than Windsor) with Monorail ? (any website link, tutorial, or code sample (preferably using Ninject 2))
fyi, I'm using C#
I don't think there's any documentation about this, but it's quite simple really. There's no magic to it. Since MonoRail and Windsor are completely separate projects, all you have to do is see how they integrate, then do the same for Ninject instead of Windsor.
More concretely, start with the MonoRailFacility which is the root of the integration. Instead of a Windsor facility, you'd use a Ninject module. Note it registers some components: IControllerTree, IWizardPageFactory, etc. The most important is IControllerFactory, which lets you resolve controllers from the container (in your case Ninject). You can leave all others as default for now (e.g. IFilterFactory/DefaultFilterFactory), and implement them as needed (i.e. when you need container control of filters).
Then call ServiceProviderLocator.Instance.AddLocatorStrategy(new NinjectAccessorStrategy()); where NinjectAccessorStrategy is an implementation of IAccessorStrategy which returns the Ninject kernel as a Castle.Core.IServiceProviderEx (which is nothing but a trivial extension of System.IServiceProvider). Since the Ninject kernel already implements IServiceProvider, it's trivial to write an adapter for IServiceProviderEx.