I was trying to set a property in the constructor af a controller like this:
public ApplicationUserManager UserManager { get; private set; }
public AccountController()
{
UserManager = HttpContext.GetOwinContext().Get<ApplicationUserManager>("");
}
But as explained here:
https://stackoverflow.com/a/3432733/1204249
The HttpContext is not available in the constructor.
So how can I set the property so that I can access it in every Actions of the Controller?
You can move the code into a read-only property on your controller (or a base controller if you need it available across your entire application):
public class AccountController : Controller {
private ApplicationUserManager userManager;
public ApplicationUserManager UserManager {
if (userManager == null) {
//Only instantiate the object once per request
userManager = HttpContext.GetOwinContext().Get<ApplicationUserManager>("");
}
return userManager;
}
}
Related
I have this custom delegating handler:
public class CustomHandler : DelegatingHandler
{
private readonly TokenProvider tokenProvider;
private readonly ProtectedSessionStorage sessionStorage;
public CustomHandler(
TokenProvider tokenProvider,
ProtectedSessionStorage sessionStorage) : base(new HttpClientHandler())
{
this.tokenProvider = tokenProvider ?? throw new ArgumentNullException(nameof(tokenProvider));
this.sessionStorage = sessionStorage ?? throw new ArgumentNullException(nameof(sessionStorage));
}
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken ct)
{
return await base.SendAsync(request, ct).ConfigureAwait(false);
}
}
The TokenProvider class stores tokens:
public class TokenProvider
{
public string AccessToken { get; set; }
public string IdToken { get; set; }
public string RefreshToken { get; set; }
}
Injecting these classes into a razor component work as expected.
I added an Api controller to the app:
[Route("api/[controller]")]
[ApiController]
public class UploadController : ControllerBase
{
private readonly TokenProvider tokenProvider;
private readonly ProtectedSessionStorage sessionStorage;
private readonly ILogger<UploadController> logger;
public UploadController(
TokenProvider tokenProvider,
ProtectedSessionStorage sessionStorage,
ILogger<UploadController> logger)
{
this.tokenProvider = tokenProvider;
this.sessionStorage = sessionStorage;
this.logger = logger;
}
}
However, when the controller is instantiated, both TokenProvider and ProtectedSessionStorage are null or empty.
Is it even possible to get instances of these classes using DI? And if not, is there an alternative solution?
ProtectedSessionStorage, cannot not be injected in a C# class. It should only be used in a Blazor component. See the Microsoft docs which state...
"Protected Browser Storage relies on ASP.NET Core Data Protection and is only supported for Blazor Server apps."
https://learn.microsoft.com/en-us/aspnet/core/blazor/state-management?view=aspnetcore-6.0&pivots=server
I Have a PhoneBook Project in MVC and use IUnitOfWork .
but I dont Know that How do this project.
the link of the project :
http://www.mediafire.com/download/jy0b5ins5eisy5t/MvcAppPhoneBook.rar
please complate thie project for me
i'm doing CRUD in this project.
I've used generic repo and UoW in my projects as below. You can take reference of this to complete your project. I usually have 4 layer solution architecture:
Core
Model classes
Data
Generic Repo and UoW
DbContext
Code first migrations
Web
applications solution with dependency injection implementation (e.g.Ninject)
Test
Model classes
public class User
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Course
{
public int Id { get; set; }
public string Name { get; set; }
}
MyDbContext.cs:
public class MyDbContext : DbContext
{
public MyDbContext() : base("name=DefaultConnection”)
{
}
public System.Data.Entity.DbSet<User> Users { get; set; }
public System.Data.Entity.DbSet<Course> Courses { get; set; }
}
Unit of Work:
public class UnitOfWork : IUnitOfWork
{
//private variable for db context
private MyDbContext _context;
//initial db context variable when Unit of Work is constructed
public UnitOfWork()
{
_context = new MyDbContext();
}
//property to get db context
public MyDbContext Context
{
//if not null return current instance of db context else return new
get { return _context ?? (_context = new MyDbContext()); }
}
//save function to save changes using UnitOfWork
public void Save()
{
_context.SaveChanges();
}
}
Generic Repository:
public class RepositoryBase<T> : IRepositoryBase<T> where T : class
{
protected readonly IUnitOfWork _unitOfWork;
private readonly IDbSet<T> _dbSet;
public RepositoryBase(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
_dbSet = _unitOfWork.Context.Set<T>();
}
public virtual void Save()
{
_unitOfWork.Save();
}
public virtual void Add(T entity)
{
_dbSet.Add(entity);
_unitOfWork.Save();
}
//Similarly you can have Update(), Delete(), GetAll() implementation here
}
Entity Repository inheriting from generic repo:
public class UserRepository:RepositoryBase<User>,IUserRepository
{
public UserRepository(IUnitOfWork unitOfWork) : base(unitOfWork)
{
}
//Here you can also define functions specific to User
}
controller.cs
public class UserController : Controller
{
private readonly IUserRepository _dbUserRepository;
public UserController(IUserRepository dbUserRepository)
{
_dbUserRepository = dbUserRepository;
}
// GET: /User/
public ActionResult Index()
{
var users = _dbUserRepository.GetAll();
return View(users.ToList());
}
//Other CRUD operations
}
I'm using MVC pattern in my application. For each model class I have a controller one. All controller classes have a saveOrUpdate() method. I am wondering if this is enough to create an Interface which defines said method, and then all controller implements it.
Please note that saveOrUpdate() receive a model class as a parameter. So it would be something like UserController#saveOrUpdate(User user), CourseController#saveOrUpdate(Course course), AppleManager#saveOrUpdate(Apple apple).
I think what you need is generic repository which implements generic functionality for a given entity. I've recently started implementing Repository Pattern along with Unit of Work in my MVC projects. Here is how I do that.
MyDbContext.cs:
public class MyDbContext : DbContext
{
public MyDbContext() : base("name=DefaultConnection”)
{
}
public System.Data.Entity.DbSet<User> Users { get; set; }
public System.Data.Entity.DbSet<Course> Courses { get; set; }
}
Unit of Work:
public class UnitOfWork : IUnitOfWork
{
//private variable for db context
private MyDbContext _context;
//initial db context variable when Unit of Work is constructed
public UnitOfWork()
{
_context = new MyDbContext();
}
//property to get db context
public MyDbContext Context
{
//if not null return current instance of db context else return new
get { return _context ?? (_context = new MyDbContext()); }
}
//save function to save changes using UnitOfWork
public void Save()
{
_context.SaveChanges();
}
}
Generic Repository:
public class RepositoryBase<T> : IRepositoryBase<T> where T : class
{
protected readonly IUnitOfWork _unitOfWork;
private readonly IDbSet<T> _dbSet;
public RepositoryBase(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
_dbSet = _unitOfWork.Context.Set<T>();
}
public virtual void Save()
{
_unitOfWork.Save();
}
public virtual void Add(T entity)
{
_dbSet.Add(entity);
_unitOfWork.Save();
}
//Similarly you can have Update(), Delete(), GetAll() implementation here
}
Entity Repository inheriting from generic repo:
public class UserRepository:RepositoryBase<User>,IUserRepository
{
public UserRepository(IUnitOfWork unitOfWork) : base(unitOfWork)
{
}
//Here you can also define functions specific to User
}
Controller:
public class UserController : Controller
{
private readonly IUserRepository _dbUserRepository;
public UserController(IUserRepository dbUserRepository)
{
_dbUserRepository = dbUserRepository;
}
// GET: /User/
public ActionResult Index()
{
var users = _dbUserRepository.GetAll();
return View(users.ToList());
}
}
create an interface
interface ISave
{
void Save(object obj);
}
now in your controller implement it.
public class AppleControler : Controller , ISave
{
public void Save(Object obj)
{
//you can cast your object here.
}
}
Option two
interface ISave<T>
{
void Save(T obj);
}
public class AppleControler : Controller , ISave<Apple>
{
public void Save(Apple obj)
{
}
}
I am implementing Ninject dependency injection in an existing MVC 2 application that uses a base controller that all controllers inherit to set navigation and other information needed by the master page. When I set a controller to inherit from the base controller, I get the following error: "...BaseController' does not contain a constructor that takes 0 arguments. How do I get around this error? I am new to Ninject and can't figure this out.
public class BaseController : Controller
{
private INavigationRepository navigationRepository;
private ISessionService sessionService;
public BaseController(INavigationRepository navigationRepository, IMembershipService membershipService, ISessionService sessionService)
{
this.navigationRepository = navigationRepository;
this.sessionService = sessionService;
}
}
public class HomeController: BaseController
{ ... }
Adding that ctor is one way
public class HomeController: BaseController
{
public HomeController(INavigationRepository navigationRepository, IMembershipService membershipService, ISessionService sessionService)
: base(navigationRepository, membershipService, sessionService) { }
}
or property injection
public class BaseController : Controller
{
[Inject]
public INavigationRepository navigationRepository { get; set; }
[Inject]
public ISessionService sessionService { get; set; }
}
I just upgraded my MVC2 project to MVC3 and used the NuGet library package reference to install ninject. This created an appstart class and i used the following code to inject my IMembershipService class.
public static void RegisterServices(IKernel kernel) {
kernel.Bind<IMembershipService>().To<AccountMembershipService>();
}
This works great with my HomeController, for example.
public class HomeController : Controller
{
public IMembershipService MembershipService { get; set; }
public HomeController() : this(null) { }
public HomeController(IMembershipService service)
{
MembershipService = service;
}
HOWEVER, I am using a BaseController. Nearly the same code in the base class no longer works.
public class BaseController : Controller
{
public IMembershipService MembershipService { get; set; }
public UserService UserService { get; set; }
public BaseController() : this(null, null) { }
public BaseController(IMembershipService service, UserService userService)
{
MembershipService = service;
UserService = userService ?? new UserService();
}
If I break in the constructor of the base controller, service is just NULL. I have never used Ninject for IOC so perhaps the answer is obvious, but why will it not inject my AccountMembershipController in the base class like I want it to? I don't see what is different, although i realize the extra level of inheritance may be messing with Ninject somehow.
Your HomeController dervices from Controller, not BaseController? Also, you have a default constructor for BaseController that sets things as null. Why do you have that at all? I'd start by getting rid of those default constructors. You shouldn't need any default constructors.
I ran into this same problem myself. Assuming your code looks like this:
public HomeController : BaseController
{
}
public BaseController : Controller
{
public IMembershipService MembershipService { get; set; }
public MembershipService() { }
public MembershipService(IMembershipService service)
{
MembershipService = service;
}
}
For some reason, Ninject thinks that HomeController only has one constructor, the default parameterless one. When you put everything in HomeController, it can find the injectable constructor, but factor it out into a base class and for some reason it won't look in the base class to see if there are any overloaded constructors. There are two fixes for this:
Remove the default constructor. This is my preferred solution because it forces the constructor to be injected (like when you create the controller manually when unit testing), but the downside is that you have to implement the constructor in all your subclasses.
Keep the default constructor, but add the [Inject] attribute to all your injectable properties:
public BaseController : Controller
{
[Inject] public IMembershipService MembershipService { get;set; }
// rest is the same
}
Ninject will inject the properties correctly this way, but be aware that Ninject will call the parameterless constructor.