I have the following service interface:
public interface IGrantApplicationService
{
IEnumerable<T> GetAll();
}
Here is my implementation of the interface:
public class GrantApplicationService : IGrantApplicationService
{
public IEnumerable<GrantApplication> GetAll()
{
// Code here
}
public EditGrantApplicationViewModel CreateEditGrantApplicationViewModel()
{
// Code here
}
}
My controller:
public class GrantApplicationController : Controller
{
private IGrantApplicationService grantApplicationService;
public GrantApplicationController(IGrantApplicationService grantApplicationService)
{
this.grantApplicationService = grantApplicationService;
}
public ActionResult Create()
{
// I am trying to create my view model like this and populate it with data
EditGrantApplicationViewModel viewModel = grantApplicationService.CreateEditGrantApplicationViewModel();
return View(viewModel);
}
}
Please see in my Create method, I am trying to create my view model through the service, but when I click . then there doesn't seem to be an option to select CreateEditGrantApplicationViewModel, only GetAll is there. Why is this? I have all the correct references.
You need to define
EditGrantApplicationViewModel CreateEditGrantApplicationViewModel();
on your IGrantApplicationService interface.
At the moment the controller only knows about what is on the interface not the class.
Your grantApplicationService field is declared as IGrantApplicationService but your method CreateEditGrantApplicationViewModel is not in the interface. Just add CreateEditGrantApplicationViewModel in the interface and you'll be fine.
Related
How to call a new method which is implemented in the concrete class of an interface
I am using structure map IOC container.
public interface ICompanyRepository
{
IEnumerable<Company> GetAll();
Company Get(int id);
Company Add(Company item);
bool Update(Company item);
bool Delete(int id);
}
public class CompanyRepository: ICompanyRepository
{
// Provide implementation for all interface methods
//Class CompanyRepository will also have the new method called DisplayLog
public void DisplayLog()
{
//To do
}
}
I am trying to implement DI using structure map in my Customer controller class
how can I tell the that I need methods ofcompany2 to be called?
_.Scan(x =>
{
x.TheCallingAssembly();
x.AddAllTypesOf<ICompanyRepository>();
// or
});
My code:
private readonly ICustomerRepository customerRepository;
public CustomerController(ICustomerRepository CustomerRepository)
{
customerRepository = CustomerRepository;
}
// GET: Customer
public ActionResult Index()
{
var customers = customerRepository.DisplayLog()
//Here i need to call CompanyRepository class methods DisplayLog() how can i call it here ?
// method DisplayLog() is not be shown here
return View(customers);
}
On an Interface, you can only call what is defined in the Interface - Its a definition of a "common base" of all classes that implement it. Ask yourself: What should happen if the ICompanyRepository you get is of a type that does NOT implement DisplayLog?
That means: It is not possible to call anything else than the interface methods right away.
To call DisplayLog on customerRepository there are 3 ways:
Add DisplayLog() to the Interface
Cast the customerRepository to CompanyRepository. but this will cause an exception, if the customerRepository is of any other type than CompanyRepository
Use a second interface
After all, I'm not quite sure if what you're doing is DI. In my understanding of DI it should be something like this:
public ActionResult Index(ILogDisplay display)
{
var customers = display.DisplayLog(customerRepository);
return View(customers);
}
ILogDisplay is being a new Interface for a separate class to be injected
public interface ILogDisplay
{
public YourResultType DisplayLog(ICustomerRepository);
}
In this example you actually inject a dependency (the implementation of ILogDisplay) in your class.
There's a couple of questions to raise here:
Why does the repository know how to display a log?
What does DisplayLog() mean in the context of a CustomerRepository?
Why should the controller even care about what the repository is logging?
Why is DisplayLog assigning a variable called customers when its return type is clearly void?
Fundamentally, the behaviour of your repository should be unknown to your controller, this is the essence of the Inversion of Control principle. All it cares about is that given the explicit contract provided by the interface for a repository, a method call will return customers. Logging is a concern of the repository.
A fairly traditional setup, from a DI point of view us the following:
ICompanyRepository:
public interface ICompanyRepository() {
IEnumerable<Company> GetAll();
Company Get(int id);
Company Add(Company item);
bool Update(Company item);
bool Delete(int id);
}
CustomerRepository:
public class CompanyRepository: ICompanyRepository
{
private readonly ILogger logger;
public CompanyRepository(ILogger logger) {
this.logger = logger;
}
// Provide implementation for all interface methods
public Company Get(int id) {
var customers = this.randomCustomerSource.Get(id);
this.logger.Info("Whatever you want to log here");
return customers;
}
}
CustomerController:
public class CustomerController {
private readonly ICustomerRepository customerRepository;
public CustomerController(ICustomerRepository CustomerRepository)
{
customerRepository = CustomerRepository;
}
// GET: Customers
public ActionResult Index()
{
var customers = customerRepository.GetAll()
return View(customers);
}
}
So the repository requests an Ilogger, the controller requests a ICompanyRepository, and will just call GetAll() and return the results. Usually there's a bit more involved but that's the very basic gist of a workflow for a controller that returns data.
Normally I do my data access by instanciating my DbContext globally in my Controller and then I use that manipulate my data.
See below:
public class UserController : Controller
{
private OrtundEntities db = new OrtundEntities();
public ActionResult Create(CreateUserViewModel model)
{
try
{
UserDataModel user = new UserDataModel
{
// map view model fields to data model ones
};
db.Users.Add(user);
db.SaveChanges();
}
catch (Exception ex)
{
// some or other error handling goes here
}
}
}
It occurs to me that this might not be the ideal way to do it in all applications but aside from implementing a web service for every project I do, I can't think of any alternatives to the above.
So what's a better way to handle the data access on larger projects where the above wouldn't be ideal?
I'm just looking for so-called "best practice" for this or that particular situation. Many opinions will differ on what's the best way so what do you think it is and why?
To help keep your controllers concise and free of direct access to your database, you can implement the repository and dependency injection patterns. For even more concise code, you can also use the unit of work pattern.
Say you had this model:
public class Person {
public int Id { get; set; }
public string Name { get; set; }
}
With the help of generics, you can create an interface to provide a CRUD blueprint:
public interface IRepository<T> {
IEnumerable<T> Get();
T Get(int? i);
void Create(T t);
void Update(T t);
void Delete(int? i);
}
Then create a Repository class that implements the IRepository. This is where all your CRUD will take place:
public class PersonRepository : IRepository<Person> {
private OrtundEntities db = new OrtundEntities();
public IEnumerable<Person> Get() {
return db.Persons.ToList();
}
//invoke the rest of the interface's methods
(...)
}
Then in your controller you can invoke the dependency injection pattern:
private IRepository<Person> repo;
public PersonController() : this(new PersonRepository()) { }
public PersonController(IRepository<Person> repo) {
this.repo = repo;
}
And your controller method for, say, Index() could look like this:
public ActionResult Index() {
return View(repo.Get());
}
As you can see this has some useful benefits, including structure to your project, and keeping your controllers easy to maintain.
I think you need to read this
http://chsakell.com/2015/02/15/asp-net-mvc-solution-architecture-best-practices/
Larger proyets ?
Maybe https://msdn.microsoft.com/es-es/library/system.data.sqlclient.sqlcommand(v=vs.110).aspx
I use this in some big requests.
I want access base class member in our Log Aspect Class. I have one base controller & that controller inherit by Test controller & in Test Controller i implemented AOP Aspect.
In BaseContoller i have a member _userSession. I initializing _userSession when BaseContoller's Constructor is call. And after call TestController first AOP Aspect is called. I want Access _userSession on OnEntry method of AOP.
LogAspect Class
[Serializable]
[MulticastAttributeUsage(MulticastTargets.Method)]
public class LogAspect:PostSharp.Aspects.OnMethodBoundaryAspect
{
public object UserData;
public override void OnEntry(PostSharp.Aspects.MethodExecutionArgs args)
{
LogManager.Info(string.Format("Starting - {0}-{0}",args.Instance, new StackTrace().GetFrame(1).GetMethod().Name));
// want access PCX.Portal.Controllers.BaseController._userSession member here its showing in quick watch like this
//((PCX.Portal.Controllers.BaseController)(args.Instance))._userSession
LogManager.Info(string.Format("User data - {0}", FrameworkHelper.Helper.JSONHelper.GetJSON(UserData)));
if(args.Arguments.Count>0)
{
foreach (var item in args.Arguments)
{
LogManager.Info(string.Format("arguments - {0}", FrameworkHelper.Helper.JSONHelper.GetJSON(item)));
}
}
base.OnEntry(args);
}
Base controller
public class BaseController : Controller
{
public UserSession _userSession { set; get; }
AuthenticationManager _authenticationManager = new AuthenticationManager();
public BaseController()
{
//initializing _userSession here
_userSession.userid=4 ;
_userSession.customerId=5 ;
}
}
Test Controller
[LogAspect]
public class TestController : BaseController
{
public ActionResult Index()
{
return View();
}
}
As documentation states:
MethodExecutionArgs class contains property Instance that:
Gets or sets the object instance on which the method is being executed.
as long as your method is not static you will get the object that is the this inside that method. Now you need to just cast it to BaseController as your property is public you will be able to access it.
if(args.Instance != null){
var baseController = (BaseController)args.Instance;
baseController._userSession
}
Although this is what you asked for I feel a need to remark that this approach limits your aspects usability to only instance methods of classes that inherit from BaseController. If you are able to create/retrieve form somewhere the session data in that parameterless constructor you can do it in aspect as well.
I'm creating my first C# MVC site and quite early on I've hit a roadblock where I'm not sure if I'm going about things entirely the wrong way and I can't find an example similar to my own online but it seems like what I'm trying to do should be straightforward.
Basically, I have my initial controller (called ClientController) that sets up a list of clients and then displays them in my list view:
public class ClientController : Controller
{
private readonly IClientManagerRepository _clientManagerRepository;
public ClientController()
: this(new EntityClientManagerRepository())
{
}
public ClientController(IClientManagerRepository repository)
{
_clientManagerRepository = repository;
}
//
// GET: /Client/
public ViewResult List()
{
return View(_clientManagerRepository.GetAllClients());
}
}
Then in my view I have an action link where I want to route to my UserController, passing it the client name, so that it can build the list of users for that particular client.
#Html.ActionLink("View Admin Users","Index","User",new {clientName = item.ClientName},null)
This works with the following code:
public class UserController : Controller
{
private IUserManagerRepository _userManagerRepository;
//
// GET: /User/
public ActionResult Index(string clientName)
{
_userManagerRepository = new EntityUserManagerRepository(clientName);
return View(_userManagerRepository.GetAllUsers());
}
}
And my list of users is displayed correctly in my view.
However, when I then add in my details action method it doesn't work because the _userManagerRepository isn't instantiated:
//
// GET: /User/Details/5
public ActionResult Details(int contactId)
{
return View(_userManagerRepository.GetUser(contactId));
}
I would have to I guess pass in the clientname each time and re-instantiate my _userManagerRepository. That doesn't feel like a very good way though.
Ideally I'd like to create my _userManagerRepository in the constructor of my UserController. I've been looking into how I would do this so I'd have something like:
public class UserController : Controller
{
private IUserManagerRepository _userManagerRepository;
public UserController(string clientname)
: this(new EntityUserManagerRepository(clientname))
{
}
public UserController(IUserManagerRepository repository)
{
_userManagerRepository = repository;
}
I've researched that I can create my own controller factory so that I can have a parameter in my userController constructor however I still don't understand how I would pass my clientname parameter form a view to my UserController.
If you want to instantiate Repository class in controller's constructor,you can use NInject,
it's really nice approach to do it.
1-Install Ninject from Nuget
2-Create Repository Abstract for example ICustomerRepository
public abstract ICustomerRepository
{
string GetCustomerName();
}
3-Create Repository for example CustomerRepository
public class CustomerRepository:ICustomerRepository
{
string GetCustomerName()
{
return ("John");
}
}
4-create CustomerControllerFactory Class
public class CustomControllerFactory : DefaultControllerFactory
{
private static IKernel ninjectKernel;
public CustomControllerFactory()
{
ninjectKernel = new StandardKernel();
AddBindings(ninjectKernel);
}
protected override IController GetControllerInstance
(System.Web.Routing.RequestContext requestContext, Type controllerType)
{
if (controllerType == null)
{
return (new Controllers.MessageController());
}
else
{
return ((IController)ninjectKernel.Get(controllerType));
}
}
public static void AddBindings(IKernel ninjectKernel)
{
Common.DependencyInjection.DependencyManager.GetDependencyInjections().ForEach(current =>
{
if (current.Abstract != null && current.Implementation != null)
{
ninjectKernel.Bind(current.Abstract).To(current.Implementation);
}
});
ninjectKernel.Bind<ICustomerRepository>().To(typeof(CustomerRepository));
}
}
ninjectKernel.Bind().To(typeof(CustomerRepository));
I bind ICustomerRepository to CustomerRepository in upper code
5- Add below code to Application_Start
ControllerBuilder.Current.SetControllerFactory(new CustomControllerFactory());
6-Create New Controller
public class CustomerController:Controller
{
public CustomerController(ICustomerRepository customerRepository)
{
//customerRepository instantiate to CustomerRepostory Class automatically
}
}
it's Dependency Injection that i think useful for you
Regards
In an attempt to DRY up my code today i'd like to do the following. (I don't know if its the best way, but it seems better than to have an ever increasing code base where I continually need to update multiple methods if i want to change something across the whole site)
What i know about Inheritance is scary. As Iv'e never questioned any of the code/libraries that I use, and Iv'e never really attempted writing anything like this before, but I want to learn... Hoping this will be my day of enlightenment :P
To my question:
Say Iv'e got an add method (in all my controllers) like this:
public ActionResult Add(VM_Down_Time_Capture viewModel)
{
using (Down_Time_CaptureRepository repository = new Down_Time_CaptureRepository())
{
if (!ModelState.IsValid)
return ReturnValidationFailure(ViewData.ModelState.Values);
Down_Time_Capture model = new Down_Time_Capture();
model.InjectFrom(viewModel);
string mserMsg = repository.Add(model, User.Identity.Name);
if (!string.IsNullOrEmpty(mserMsg))
return ReturnCustomValidationFailure(Server.HtmlEncode(mserMsg));
repository.Save();
return Json("Added successfully.", JsonRequestBehavior.AllowGet);
}
}
And at the moment I've got the following as well.
Generated by T4 Templates/EF.
ViewModels, Repositories, (Standard) EF Models
I'm thinking I need a ModelSpecfic base controller for each page (can be done using T4), that inherits from a custom ControllerBase class that contains the basic CRUD functionality. That way i can have custom code per controller, and my code base will be cleaner & smaller & that wont get affected should i need to regenerate the base files
I don't quite understand how to implement something in the lines of what i need. What i understand so far is that ill need to have my repositories, and view models inherit from a base as well and somehow specify in [B] which ones I'm using... but as to how to do that i don't know
For example (and this is my best attempt at it, not my actual code, extremely hacky as I'm amazingly confused :S)
public class Down_Time_CaptureController : Down_Time_CaptureBase
{
//[A]
}
//Generated by T4
public class Down_Time_CaptureBase: ControllerBase
{
//[B]
public override EntityObject CreateNewModel()
{
return new Down_Time_Capture();
}
public override Base_Repository CreateNewRepository()
{
return new Down_Time_CaptureRepository();
}
public override Base_ViewModel CreateNewViewModel()
{
return new VM_Down_Time_Capture();
}
//how would i go about specifying which repository & model & view model to use
//although i expect it to be something to what i did here above
//and how would i go about calling the new generic add method (but in context of this controller)?
}
//coded once
public abstract class ControllerBase: Controller
{
//[C]
//make abstract so i have to override it
public abstract Base_Controller CreateNewModel();
public abstract Base_Controller CreateNewRepository();
public abstract Base_Controller CreateNewViewModel();
//I'm assuming my generified add method would go in here
public virtual ActionResult Add(Base_ViewModel viewModel)
{
using (Base_Repository repository = CreateRepository())
{
if (!ModelState.IsValid)
return ReturnValidationFailure(ViewData.ModelState.Values);
EntityObject model = CreateNewModel();
model.InjectFrom(viewModel);
string mserMsg = repository.Add(model, User.Identity.Name);
if (!string.IsNullOrEmpty(mserMsg))
return ReturnCustomValidationFailure(Server.HtmlEncode(mserMsg));
repository.Save();
return Json("Added successfully.", JsonRequestBehavior.AllowGet);
}
}
}
Here's a simple generic interpretation of what you are asking for:
// concrete controller implementation
public class Down_Time_CaptureController: ControllerBase<Down_Time_Capture, VM_Down_Time_Capture, Down_Time_CaptureRepository>
{
}
// generic controller base
public abstract class ControllerBase<TModel, TViewModel, TRepository>: Controller
where TModel : Base_Model, new()
where TViewModel : Base_ViewModel, new()
where TRepository : Base_Repository, new()
{
protected virtual TModel CreateNewModel()
{
return (TModel)Activator.CreateInstance<TModel>();
}
protected virtual TRepository CreateNewRepository()
{
return (TRepository)Activator.CreateInstance<TRepository>();
}
protected virtual TViewModel CreateNewViewModel()
{
return (TViewModel)Activator.CreateInstance<TViewModel>();
}
//I'm assuming my generified add method would go in here
public virtual ActionResult Add(TViewModel viewModel)
{
using (var repository = CreateRepository())
{
if (!ModelState.IsValid)
return ReturnValidationFailure(ViewData.ModelState.Values);
var model = CreateNewModel();
model.InjectFrom(viewModel);
string mserMsg = repository.Add(model, User.Identity.Name);
if (!string.IsNullOrEmpty(mserMsg))
return ReturnCustomValidationFailure(Server.HtmlEncode(mserMsg));
repository.Save();
return Json("Added successfully.", JsonRequestBehavior.AllowGet);
}
}
}
A few notes:
You will probably want to create interfaces for the three types (Model, ViewModel, Repository) and use those as the generic constraints.
You will probably want a generic Repository interface and base implementation (so you don't have to code each repository independently, and copy similar logic from one to the other).
Consider using an Inversion of Control container and dependency injection. Rather than have the controller, for example, handle creating an instance of a repository, make it a property and set it from the constructor. You can then use an IoC of your choice (like Ninject or Autofac) and register concrete implementations, and it will manage creating and the lifetime of both the dependencies and the controller itself.