Where to define AutoMapper mappings? - asp.net-mvc-3

Where in my ASP.NET MVC application should I define my AutoMapper mappings?
Mapper.CreateMap<User, UserViewModel>();
Presently I am defining these in the constructor of a BaseController, which all my Controlllers derive from. Is this the best place?

I think it's kind of late to answer the question, but maybe someone can use my answer.
I use Ninject to resolve dependencies, so I've created Ninject Module for AutoMapper. Here is the code:
public class AutoMapperModule : NinjectModule
{
public override void Load()
{
Bind<IConfiguration>().ToMethod(context => Mapper.Configuration);
Bind<IMappingEngine>().ToMethod(context => Mapper.Engine);
SetupMappings(Kernel.Get<IConfiguration>());
Mapper.AssertConfigurationIsValid();
}
private static void SetupMappings(IConfiguration configuration)
{
IEnumerable<IViewModelMapping> mappings = typeof(IViewModelMapping).Assembly
.GetExportedTypes()
.Where(x => !x.IsAbstract &&
typeof(IViewModelMapping).IsAssignableFrom(x))
.Select(Activator.CreateInstance)
.Cast<IViewModelMapping>();
foreach (IViewModelMapping mapping in mappings)
mapping.Create(configuration);
}
}
As you can see on load it scans assembly for implementaion of IViewModelMapping and then runs Create method.
Here is the code of IViewModelMapping:
interface IViewModelMapping
{
void Create(IConfiguration configuration);
}
Typical implementation of IViewModelMapping looks like this:
public class RestaurantMap : IViewModelMapping
{
public void Create(IConfiguration configuration)
{
if (configuration == null)
throw new ArgumentNullException("configuration");
IMappingExpression<RestaurantViewModel, Restaurant> map =
configuration.CreateMap<RestaurantViewModel, Restaurant>();
// some code to set up proper mapping
map.ForMember(x => x.Categories, o => o.Ignore());
}
}

As mentioned in this answer, AutoMapper has now introduced configuration profiles to organise your mapping configuration.
So for example, you could define a class to set up your mapping configuration:
public class ProfileToOrganiseMappings : Profile
{
protected override void Configure()
{
Mapper.CreateMap<SourceModel, DestinationModel>();
//other mappings could be defined here
}
}
And then define a class to initialise the mappings:
public static class AutoMapperWebConfiguration
{
public static void Configure()
{
Mapper.Initialize(cfg =>
{
cfg.AddProfile(new ProfileToOrganiseMappings());
//other profiles could be registered here
});
}
}
And then finally, call that class in your global.asax Application_Start() to configure those mappings:
protected void Application_Start()
{
...
AutoMapperWebConfiguration.Configure();
}

The code you are referencing looks like AutoMapper, not StructureMap.
If you're using the static Mapper
method, configuration only needs to
happen once per AppDomain. That means
the best place to put the
configuration code is in application
startup, such as the Global.asax file
for ASP.NET applications. Typically,
the configuration bootstrapper class
is in its own class, and this
bootstrapper class is called from the
startup method.
http://automapper.codeplex.com/wikipage?title=Getting%20Started&referringTitle=Home

Related

How can i use custom dbcontext (Audit Log) with sharprepository

I have a custom dbcontext which name is Tracker-enabled DbContext (https://github.com/bilal-fazlani/tracker-enabled-dbcontext).I want to use it for audit log
And how can I implement EFRepository?
I implemented tracker-enabled-context but i cant solve how override sharp repo commit method.
public class HayEntities : TrackerContext
{
static HayEntities()
{
Database.SetInitializer<HayEntities>(null);
}
public HayEntities() : base(HayEntities)
{
this.Configuration.ProxyCreationEnabled = false;
this.Configuration.LazyLoadingEnabled = true;
this.Configuration.ValidateOnSaveEnabled = false;
}
public DbSet<Dummy> Dummys{ get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new DummyConfiguration());
} }
}
public class DummyRepository : ConfigurationBasedRepository<DE.Dummy, long>, IDummyRepository
{
private readonly IRepository<DE.Dummy, long> _servisHasarRepository;
public DummyRepository (HayEntities hayEntities, ICachingStrategy<DE.Dummy, long> cachingStrategy = null)
{this.CachingEnabled = false;
_dummyRepository = new EfRepository<DE.Dummy, long>(hayEntities, cachingStrategy);
}
public void UpdateOrCreate() {
//In this area how can override save/commit method
}
}
You will want to tell SharpRepository to use an IoC provider to inject the DbContext. This will take care of getting the proper DbContext for your EfRepository.
If you want to control things based on the configuration and have custom repositories so you can implement your own mehods like UpdateOrCreate() then you would inherit from ConfigurationBasedRepository as you have in the example.
There are more details on setting up IoC with SharpRepository here: http://fairwaytech.com/2013/02/sharprepository-configuration/ (look in the "Entity Framework and Sharing the DbContext" section)
First look on NuGet for SharpRepository.Ioc.* to find the specific IoC you are using. If you are using StructureMap then you would do something like this.
In your StructureMap configuration:
// Hybrid (once per thread or ASP.NET request if you’re in a web application)
For<DbContext>()
.HybridHttpOrThreadLocalScoped()
.Use<HayEntities>()
.Ctor<string>("connectionString").Is(entityConnectionString);
Then you need to tell SharpRepository to use StructureMap by calling this in your startup code:
RepositoryDependencyResolver.SetDependencyResolver(new StructureMapDependencyResolver(ObjectFactory.Container));
After doing these things, then if you use EfRepository then it will know to ask StructureMap for the DbContext.
Now in your example above where you are using ConfigurationBasedRepository, I would suggest setting the caching in the configuration file instead of in code since you are using the configuration to load the repository. Since IoC is handling the DbContext you don't need to do anyhing with that and you can focus on the custom method you want to write.
public class DummyRepository : ConfigurationBasedRepository<DE.Dummy, long>, IDummyRepository
{
public void UpdateOrCreate()
{
// You have access to the underlying IRepository<> which is going to be an EfRepository in your case assuming you did that in the config file
// here you can call Repository.Add(), or Reposiory.Find(), etc.
}
}

how to use EntityFramework.patterns with ninject in MVC 3?

I'm trying to use EntityFramework.Patterns package from nuget , but i'm stuck,here is my
question : how to use ninject to inject productRepo and unitOfWork within a mvc Controller ?
here is the tutorial link : http://efpatterns.codeplex.com/wikipage?title=Pattern%20%3a%20Use%20Repository%20and%20UOF
DbContextAdapter adapter = new DbContextAdapter(ctx);
IRepository<Product> productRepo = new Repository<Product>(adp);
IUnitOfWork unitOfWork = new UnitOfWork(adp);
Add a constructor taking them as arguments to the Controller. Search for constructor injection for more details.
Download Ninject.MVC3 package from nuget.
Remove the "ninject web common" piece from your AppStart folder
Open your global.asax and change your code to look like to following
namespace OnBoardingMVC
{
public class MvcApplication : Ninject.Web.Common.NinjectHttpApplication
{
protected override IKernel CreateKernel()
{
var kernel = new StandardKernel();
NinjectConfig.RegisterServices(kernel);
return kernel;
}
protected override void OnApplicationStarted()
{
base.OnApplicationStarted();
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
}
}
Then you can create a new NinjectConfig.cs file in your App_Start folder and add the following code to your class:
namespace OnBoardingMVC
{
public class NinjectConfig
{
public static void RegisterServices(IKernel kernel)
{
// e.g. kernel.Load(Assembly.GetExecutingAssembly());
kernel.Bind(typeof(IEmployeeUow))
.To(typeof(EmployeeUow))
.WithConstructorArgument("adapter", <Add new AdapterVariable here>)
;
}
}
}
You could then create an EmployeeUow class that inherits from the UnitOfWork class and also create a IEmployeeUow that inherits from the IUnitOfWork and the context adapter would be a parameter for the constructor and that construtor would also pass the adapter to the base constructor of the UnitOfWork class.

RavenDB with Ninject in ASP.NET MVC3

I want to use RavenDB with ninject in my asp.net mvc3 project, Any idea how I have to configure this?
kernel.Bind<Raven.Client.IDocumentSession>()
.To<Raven.Client.Document.DocumentStore>()
.InSingletonScope()
.WithConstructorArgument("ConnectionString", ConfigurationManager.ConnectionStrings["RavenDB"].ConnectionString);
Here's how I do mine:
If you install Ninject with Nuget, you'll get an /App_start/ NinjectMVC3.cs file. In there:
private static void RegisterServices(IKernel kernel)
{
kernel.Load<RavenModule>();
}
Here's the RavenModule class:
public class RavenModule : NinjectModule
{
public override void Load()
{
Bind<IDocumentStore>()
.ToMethod(InitDocStore)
.InSingletonScope();
Bind<IDocumentSession>()
.ToMethod(c => c.Kernel.Get<IDocumentStore>().OpenSession())
.InRequestScope();
}
private IDocumentStore InitDocStore(IContext context)
{
DocumentStore ds = new DocumentStore { ConnectionStringName = "Raven" };
RavenProfiler.InitializeFor(ds);
// also good to setup the glimpse plugin here
ds.Initialize();
RavenIndexes.CreateIndexes(ds);
return ds;
}
}
And for completeness here's my index creation class:
public static class RavenIndexes
{
public static void CreateIndexes(IDocumentStore docStore)
{
IndexCreation.CreateIndexes(typeof(RavenIndexes).Assembly, docStore);
}
public class SearchIndex : AbstractMultiMapIndexCreationTask<SearchIndex.Result>
{
// implementation omitted
}
}
I hope this helps!
I recommend using a custom Ninject Provider to set up your RavenDB DocumentStore. First place this in your code block that registers your Ninject services.
kernel.Bind<IDocumentStore>().ToProvider<RavenDocumentStoreProvider>().InSingletonScope();
Next, add this class that implements the Ninject Provider.
public class RavenDocumentStoreProvider : Provider<IDocumentStore>
{
var store = new DocumentStore { ConnectionName = "RavenDB" };
store.Conventions.IdentityPartsSeparator = "-"; // Nice for using IDs in routing
store.Initialize();
return store;
}
The IDocumentStore needs to be a singleton, but do not make the IDocumentSession a singleton. I recommend that you simply create a new IDocumentSession using OpenSession() on the IDocumentStore instance Ninject gives you whenever you need to interact with RavenDB. IDocumentSession objects are very lightweight, follow the unit-of-work pattern, are not thread-safe, and are meant to be used and quickly disposed where needed.
As others have done, you might also consider implementing a base MVC controller that overrides the OnActionExecuting and OnActionExecuted methods to open a session and save changes, respectively.

Accessing ninject kernel in Application_Start

I am using Ninject and the MVC3 extension installed with nuget. My kernel setup code is in the App_Start/NinjectMVC3.cs file. Everything works great in controllers, but I can't figure out how to (properly) bind interfaces in the Global.asax.cs MvcApplication code.
I ended up using a hack (creating a public NinjectMVC3.GetKernel() method that returns bootstrap.kernel). However, that will be deprecated, and there must be a proper way to do this that I am not seeing.
Here is my code:
public class LogFilterAttribute : ActionFilterAttribute
{
private IReportingService ReportingService { get; set; }
public LogFilterAttribute( IReportingService reportingService )
{
this.ReportingService = reportingService;
}
...
}
public class MvcApplication : System.Web.HttpApplication
{
public static void RegisterGlobalFilters( GlobalFilterCollection filters )
{
filters.Add( new HandleErrorAttribute() );
filters.Add( new LogFilterAttribute() );
}
...
protected void Application_Start()
{
...
RegisterGlobalFilters( GlobalFilters.Filters );
// NOTE hack:
var kernel = NinjectMVC3.GetKernel();
var logger = kernel.Get<ILogger>();
var bw = new BackgroundWork(logger);
Application["BackgroundWork"] = bw;
bw.Start();
}
}
There are two interfaces I am interested in. The first is just binding an object to a Global variable (the ILogger for the BackgroundWork).
And the second is for an ActionFilter. I read http://www.planetgeek.ch/2010/11/13/official-ninject-mvc-extension-gets-support-for-mvc3/, but I don't see how it plugs into the actual registration (filter.Add).
I don't want to use the Property Inject if I can avoid it.
Any thoughts on the proper way to do this?
Thanks
MVC 3 introduces the DependencyResolver which is populated into a singleton, and the Ninject extension supports it. You could use that in your MvcApplication class if you need it:
protected void Application_Start()
{
// ...
var logger = DependencyResolver.Current.GetService<ILogger>();
}
Now I should point out that it is unnecessary to do this with action filters. In Ninject.MVC3 you are supposed to use the BindFilter syntax, like so:
// Declare empty attribute
public class MyFilterAttribute : FilterAttribute { }
// Dependency module
public class MyModule : NinjectModule
{
public override void Load()
{
// Other bindings
// ...
this.BindFilter<MyActionFilter>(FilterScope.Action, 1)
.WhenControllerHas<MyFilterAttribute>();
}
}
Note that you have to use this because BindFilter is an extension method, and you also have to reference the Ninject.Web.Mvc.FilterBindingSyntax namespace.

How to apply a global filter in playframework

When using #before, it is only used in one class. How do I apply a global filter in playframework? So that one filter is used for all controller classes.
A simple solution is to extend a base controller for all of your controllers and have the #Before in the base controller.
The other option (and the better solution, as it is more flexible) is to use the #With annotation. The example on the play documentation is
Example:
public class Secure extends Controller {
#Before
static void checkAuthenticated() {
if(!session.containsKey("user")) {
unAuthorized();
}
}
}
And on another Controller:
#With(Secure.class)
public class Admin extends Application {
...
}
This means the Admin controller will process all the interceptors (#Before, #After, #Finally) contained within the Secure controller.
I did this very thing by handling incoming requests globally in the GlobalSettings class:
This describes the class:
http://www.playframework.org/documentation/2.0/JavaGlobal
This describes the method you'd want to override.
http://www.playframework.org/documentation/2.0/JavaInterceptors
Here's an example of how I used it in my own project (of course, this is a simplified version of what you're looking for):
#Override
public play.mvc.Action onRequest(play.mvc.Http.Request request, java.lang.reflect.Method method) {
if (request.path().startsWith("/secret/locked")) {
return new Action.Simple() {
#Override
public Result call(play.mvc.Http.Context ctx) throws Throwable {
return redirect(routes.Application.forbidden());
}
};
}
return super.onRequest(request, method);
}
You can simply use PlayPlugin for this issue. See here for more details.
It's not a good solution to extend a base controller for all of your controllers and have the #Before in the base controller.
You can extends the filter or essensialfilter .e.g.
class filter1 extends Filter {}
and apply filter1 to Global

Resources