Can i have a baseController that has all my repositories when using StructureMap? - asp.net-mvc

Historically my controllers have repositories declared on each controller which are injected through StructureMap and this is working fine for me.
But my new project will likely be using the same repositories for each controller.
Due to this i created a BaseController and inherit all controllers from here.
My repositories now live in Base but the injection is not working.
Can it work like this or does constructor injection have to take place on each controller?
public static void BootStructureMap()
{
ObjectFactory.Initialize(x =>
{
x.Scan(scanner =>
{
scanner.TheCallingAssembly();
scanner.WithDefaultConventions();
scanner.AddAllTypesOf<IController>().NameBy(type => type.Name.Replace("Controller", "").ToLower());
});
x.For(typeof(IGenericRepository<>)).Use(typeof(GenericRepository<>));
});
}
Working:
public class TransactionController : Controller
{
public IGenericRepository<ITransaction> TransactionRepository { get; set; }
public TransactionController(IGenericRepository<ITransaction> transactionRepository)
{
this.TransactionRepository = transactionRepository;
}
public ActionResult Index()
{
var transactions = this.TransactionRepository.Query.AsEnumerable();
return View(transactions);
}
Not working:
public class BaseController : Controller
{
public IGenericRepository<ITransaction> TransactionRepository { get; set; }
public BaseController(IGenericRepository<ITransaction> transactionRepository)
{
this.TransactionRepository = transactionRepository;
}
protected BaseController()
{
}
}
public class TransactionController : BaseController
{
public ActionResult Index()
{
var transactions = base.TransactionRepository.Query.AsEnumerable();
return View(transactions);
}
}

You have to inject your repository into BaseController somehow. If your last piece of code is the real code you have then it seems that BaseController is initialized through protected parameterless constructor.
Add the constructor to TransactionController:
public TransactionController(IGenericRepository<ITransaction> transactionRepository) : base(transactionRepository)
{
}

Can use Poor Man's Dependency Injection - used in NerdDinner application
public BaseController() : this(new Message())
{
}
Or
Refer Phill's link
tdd-and-dependency-injection-with-asp.net-mvc.aspx
Override DefaultControllerFactory
public class SMControllarFactory : DefaultControllerFactory
In
application start
protected void Application_Start()
{
ControllerBuilder.Current.SetControllerFactory(new SMControllarFactory());

Related

MVC:No parameterless constructor defined for this object

Server Error in '/' Application.
No parameterless constructor defined for this object.How can I resolve this issue.
I created one folder in that created interface ICompanyService and class CompanyService.
Controller:
public class HomeController : Controller
{
private ICompanyService icompanyService;
public HomeController(ICompanyService icompanyService)
{
this.icompanyService = icompanyService;
}
public ActionResult Index()
{
ViewBag.CompanyName = this.icompanyService.GetCompany();
return View();
}
}
ICompanyService:
public interface ICompanyService
{
string GetCompany();
}
CompanyService:
public class CompanyService
{
public string GetCompany()
{
return "Msc";
}
}
You need to include below constructor to your controller,
public HomeController() : this(new CompanyService())
{
}
So your entire controller code looks like below,
public class HomeController : Controller
{
private ICompanyService icompanyService;
public HomeController() : this(new CompanyService())
{
}
public HomeController(ICompanyService icompanyService)
{
this.icompanyService = icompanyService;
}
public ActionResult Index()
{
ViewBag.CompanyName = this.icompanyService.GetCompany();
return View();
}
}
This will solve your issue.
Happy coding!!!!!
CompanyService Class Should Inherits From ICompanyService Interface.
Please Study About Dependency Injection In .NET .
public class CompanyService : ICompanyService
{
public string GetCompany()
{
return "Msc";
}
}
#ravi please use dependency injection, so what service will automatically initialize your service constructor without defined constructor logic, the dependency inject handle and initialize you service object. don't worry about initialization.
below i have mention the link for IoC and i hope your issue will resolve soon.
https://github.com/quozd/awesome-dotnet/blob/master/README.md#ioc

how to implement dependency injection in mvc?

I'm trying to implement dependency injection but i know how to implement the interface and repository of classes then i don't know what shall i do.
This my sample:
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public string LastName { get; set; }
}
This is my interface:
public interface IUser
{
IEnumerable<User> GetUsers();
void AddUser(User user);
void EditUser(User user);
void DeleteUser(int id);
User UserGetById(int id);
void Save();
}
This is my repository:
public class UserRepsitory:IUser
{
private _Context _context;
public UserRepsitory(_Context _context)
{
this._context = _context;
}
public IEnumerable<User> GetUsers()
{
return _context.User.ToList();
}
public void AddUser(User user)
{
_context.User.Add(user);
}
public void EditUser(User user)
{
_context.Entry(user).State = System.Data.Entity.EntityState.Modified;
}
public User UserGetById(int id)
{
return _context.User.Find(id);
}
public void Save()
{
_context.SaveChanges();
}
public void DeleteUser(int id)
{
var Search = _context.User.Find(id);
_context.User.Remove(Search);
}
}
And one of method in controller:
private IUser userRepsitory;
public UsersController()
{
this.userRepsitory = new UserRepsitory(new _Context());
}
public UsersController(IUser UserRepository)
{
this.userRepsitory = UserRepository;
}
public ActionResult Index()
{
return View(userRepsitory.GetUsers());
}
What is the next step?
The first thing is, get rid of the default constructor where we are hard coding the initialization of UserRepository ! We will do that in the dependency injection way.
public UsersController : Controller
{
private readonly IUser userRepsitory;
public UsersController(IUser UserRepository)
{
this.userRepsitory = UserRepository;
}
public ActionResult Index()
{
return View(userRepsitory.GetUsers());
}
}
Now we need something to tell the MVC framework which version/implementation of IUser should be used when the code runs. you can use any dependency injection frameworks to do that. For example, If you are in MVC 6, you can use the inbuilt dependency injection framework to do that. So go to your Startup class and in your ConfigureServices method, you can map an interface to a concrete implementation.
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<IUser, UserRepository>();
}
}
If you are in a previous version of MVC, you may consider using any of the dependency injection frameworks available like Unity, Ninject etc.
It is pretty much same, you map an interface to a concrete implementation
Ninject
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IUser>().To<UserRepository>();
}
You do not need to put the mapping in a cs file. You can define that in a config file. For example, when you use Unity you can do something like this in your config file (web config or an external config file for unity configuration)
Unity
<alias alias="IUser" type="YourNamespace.IUser, YourAssemblyName" />
<register type="IUser" mapTo="YourNamespace.UseRepository, YourAssemblyName">
In order to create and configure your project with Spring DI(Dependency Feature) you must configure beans.
Create an xml file (if its not there) and add references to bean
In this xml file, provide references to the classes you want to inject. Example:
<bean id="Name of the JAVA Class" class="the Full path of the JAVA class"/>
And in your class where you are supposed to call the referencing class(above), calling procedure would be like :
#Controller
public class MyController {
private full.path.of.my.class.named.MyJavaClass _class;
#Autowired
private MyController (full.path.of.my.class.MyJavaClass class)
{
this._class= class;
}
}
Now say if you a function in MyJavaClass
public int sum(int x, int y){
return x+y;
}
Then without creating object of MyJavaClass you can inject like the following in your controller:
_class.Sum(10,15);
YOU DO NOT CREATE AN INSTANCE OF THIS CLASS.

.NET MVC 5.2 Inheriting attribute Routes from Base Controller

I have a base controller that contains several actions that I would like to use attribute routing on, and not have to override these methods in the controllers that inherit from the base.
As of .NET MVC 5.2 this should be possible according to this: http://www.asp.net/mvc/overview/releases/whats-new-in-aspnet-mvc-52
The example provided shows how to use a class level attribute, but I would like to Implment it at the action level. Has anyone successfuly implemented inheritance of attributes on the action level?
I see another answer .NET WebAPI Attribute Routing and inheritance claims this is possible in with web API controllers, but can it be done using the standard MVC controller?
[InheritedRoute("attributerouting/{controller}/{action=Index}/{id?}")]
public abstract class BaseController : Controller
{
}
public class BlogController : BaseController
{
public string Index()
{
return "Hello from blog!";
}
}
public class StoreController : BaseController
{
public string Index()
{
return "Hello from store!";
}
}
[AttributeUsage(AttributeTargets.Class, Inherited=true, AllowMultiple=true)]
public class InheritedRouteAttribute : Attribute, IDirectRouteFactory
{
public InheritedRouteAttribute(string template)
{
Template=template;
}
public string Name { get; set; }
public int Order { get; set; }
public string Template { get; private set; }
public new RouteEntry CreateRoute(DirectRouteFactoryContext context)
{
// context.Actions will always contain at least one action - and all of the
// actions will always belong to the same controller.
var controllerDescriptor=context.Actions.First().ControllerDescriptor;
var template=Template.Replace("{controller}",
controllerDescriptor.ControllerName);
IDirectRouteBuilder builder=context.CreateBuilder(template);
builder.Name=Name;
builder.Order=Order;
return builder.Build();
}
}
// Custom direct route provider which looks for route attributes of type
// InheritedRouteAttribute and also supports attribute route inheritance.
public class InheritedDirectRouteProvider : DefaultDirectRouteProvider
{
protected override IReadOnlyList
GetControllerRouteFactories(ControllerDescriptor controllerDescriptor)
{
return controllerDescriptor
.GetCustomAttributes(typeof(InheritedRouteAttribute), inherit: true)
.Cast()
.ToArray();
}
}
I think I have the action level working with the following code:
public class InheritedDirectRouteProvider : DefaultDirectRouteProvider
{
protected override IReadOnlyList<IDirectRouteFactory>
GetActionRouteFactories(ActionDescriptor actionDescriptor)
{
return actionDescriptor.GetCustomAttributes(typeof(IDirectRouteFactory), inherit: true).Cast<IDirectRouteFactory>().ToArray();
}
}
and call:
routes.MapMvcAttributeRoutes(new InheritedDirectRouteProvider());
this lets me inherit the controller and its routines from an abstract controller, simplified example:
// Inherited class needs to define [RoutePrefix("childPrefix")]
public abstract class ChildBaseController<TChildEntity> : BaseController where TChildEntity : ChildEntity
{
public ChildBaseController(IUnitOfWork DAL) : base(DAL) { }
protected abstract GenericChildRepository<TChildEntity> ChildRepository { get; }
protected abstract string[] GetCreateBindFields();
protected abstract string[] GetEditBindFields();
[Route("{valueId}")]
public ActionResult Index(int valueId)
{
ViewBag.ValueId = valueId;
return View(ChildRepository.Get().Where(cr => cr.ValueId == valueId));
}
... bunch more CRUD actions with [Route(...)] ...
}
inherited class:
namespace Web.Frontend.Controllers
{
[RoutePrefix("Fields")]
public class FieldsController : ChildBaseController<Field>
{
public FieldsController(IUnitOfWork DAL) : base(DAL) { }
protected override GenericChildRepository<Field> ChildRepository
{
get
{
return DAL.Fields;
}
}
protected override string[] GetCreateBindFields()
{
return new string[] { ... };
}
protected override string[] GetEditBindFields()
{
return new string[] { ... };
}
}
}

How mapping various types with a single instance using Ninject?

I have this:
public class DbContext : System.Data.Entity.DbContext, IDbContext
{
}
My Ninject configuration:
public override void Load()
{
Bind<IDbContext>().To<DbContext>().InRequestScope().WithConstructorArgument("connectionString", ConfigurationManager.AppSettings["DefaultConnectionString"]);
}
So, How I get the same instance of DbContext in another class like:
public class ExampleClass()
{
...
public ExampleClass(DbContext myDbContextDependency)
{
...
}
}
Update 1:
IDbContext is my UnitOfWork pattern, it lives in my Domain Layer:
public interface IDbContext
{
void SaveChanges();
}
And I need DbContext to use in my BaseRepository:
public abstract class BaseRepository<TEntity> : IBaseRepository<TEntity> where TEntity : Entity
{
...
//I'm using DbContext here:
protected BaseRepository()
{
this.DbSet = DbContext.Set(typeof(TEntity));
}
//and here:
public virtual void Edit(TEntity entity)
{
this.DbContext.Entry(entity).State = EntityState.Modified;
}
}
You should inject an IDbContext, not a DbContext:
public class ExampleClass()
{
...
public ExampleClass(IDbContext myDbContextDependency)
{
...
}
}
I found the solution using the Service Locator of Ninject and took back the instance of DbContext:
public class ExampleClass()
{
protected DbContext DbContext
{
get
{
//Here I do the trick I wanted
return DependencyResolverFactory.Instance.Get<IDbContext>() as DbContext;
}
}
...
}

MVC 3 + IoC + NInject + Repositories + LINQ

I'm trying to work with NInject in my MVC 3 application, and i have one question.
Interface
public interface ITalesRepository
{
IEnumerable<Tale> GetAllTales();
}
Repository
public class TalesRepository : ITalesRepository
{
private FairyTalesMVC3DataContext _dataContext;
public TalesRepository(FairyTalesMVC3DataContext dataContext)
{
_dataContext = dataContext;
}
public IEnumerable<Tale> GetAllTales()
{
return _dataContext.Tales.OrderBy(c => c.NameAn);
}
}
Home controller
public class HomeController : Controller
{
private readonly ITalesRepository _talesRepository;
public HomeController(ITalesRepository talesRepository)
{
_talesRepository = talesRepository;
}
public ActionResult Index()
{
ViewBag.Tales = _talesRepository.GetAllTales();
return View();
}
}
So, i need to initialize my TalesRepository with DataContext, and now it is so:
private void RegisterDependencyResolver()
{
var kernel = new StandardKernel();
kernel.Bind<ITalesRepository>().To<TalesRepository>().WithConstructorArgument("dataContext", new FairyTalesMVC3DataContext(ConfigurationManager.ConnectionStrings["dbFairyTalesConnectionString"].ConnectionString));
DependencyResolver.SetResolver(new NinjectDependencyResolver(kernel));
}
So, my question, is it ok or something wrong?
First of all:
public IEnumerable<Tale> GetAllTales()
{
return _dataContext.Tales.OrderBy(c => c.NameAn);
}
I would add .ToList() to the end. Else you'll get data layer exceptions in your presentation layer which is not fine.
Next, I would recommend that you switch to ViewModels instead of using ViewBag. It's a lot easier to prevent that logic leaks into the views if you are using ViewModels. Since you can add the logic to the ViewModel and thus get the same behaviour in all views using the model.
Your application should inherit from NinjectHttpApplication. It registers dependency resolver, so you don't have to do it.
You should also override CreateKernel in application class and register your own module with bindings:
public class MvcApplication : NinjectHttpApplication
{
protected override IKernel CreateKernel()
{
return new StandardKernel(new INinjectModule[] {new MvcModule()});
}
}
public class MvcModule : NinjectModule
{
public override void Load()
{
Bind<ITalesRepository>().To<TalesRepository>();
Bind<FairyTalesMVC3DataContext>().To<FairyTalesMVC3DataContext>().InRequestScope();
}
}

Resources