HttpContext(User.Identity) in Controller (asp web api) not working - c#

I have some problems with correctly working HttpContext.Current.User.Identity. From Controller constructor this doesn't work, I have to implement this to some method. Look at this example.
public class SomeControler : ApiController
{
private UserData userData;
// NOT WORKING
public ChartsController(
RegisteredUserData registeredUserData,
NotLoggedInUserData NotLoggedInUserData
{
var isAuthenticated = HttpContext.Current.User.Identity.IsAuthenticated;
this.userData = isAuthenticated
? (IUserData)registeredUserData
: (IUserData)NotLoggedInUserData;
}
// WORKING
public SomeMethod(
RegisteredUserData registeredUserData,
NotLoggedInUserData NotLoggedInUserData
{
var isAuthenticated = HttpContext.Current.User.Identity.IsAuthenticated;
this.userData = isAuthenticated
? (IUserData)registeredUserData
: (IUserData)NotLoggedInUserData;
}
}
How I can fix this? I spent a lot of time for answer in web but i didnt get this.
Regards.
edit
I found an answer. Is it good solution ?
public class SomeControler : ApiController
{
private RegisteredUserData registeredUserData;
private NotLoggedInUserData notLoggedInUserData;
private UserData userData
{
get
{
if (HttpContext.Current.User.Identity.IsAuthenticated)
{
return registeredUserData;
}
return notLoggedInUserData;
}
}
public ChartsController(
RegisteredUserData registeredUserData,
NotLoggedInUserData notLoggedInUserData
{
this.registeredUserData = registeredUserData;
this.notLoggedInUserData = notLoggedInUserData;
}
}

First, the request and HttpContext is not available yet in the construct of the controller because of where in the request flow the controller is initialized. You have to access it in an action where by then, the request and context would have been fully realized.
Next do not couple your controllers to HttpContext. It makes your code difficult to test and maintain.
Extract the desired information in a service abstraction.
public interface IUserDataAccessor {
IUserData UserData { get; }
}
public class UserDataAccessor : IUserDataAccessor {
private readonly RegisteredUserData registeredUserData;
private readonly NotLoggedInUserData notLoggedInUserData;
public UserDataAccessor(
RegisteredUserData registeredUserData,
NotLoggedInUserData notLoggedInUserData) {
this.registeredUserData = registeredUserData;
this.notLoggedInUserData = notLoggedInUserData;
}
public IUserData UserData {
get {
if (HttpContext.Current?.User?.Identity?.IsAuthenticated) {
return registeredUserData;
}
return notLoggedInUserData;
}
}
}
This allows the controller to remain lean with just the dependency on the abstraction.
public class ChartsController : ApiController {
private readonly IUserDataAccessor accessor;
public ChartsController(IUserDataAccessor accessor) {
this.accessor = accessor;
}
[HttpGet]
public IHttpActionResult SomeAction() {
var userData = accessor.UserData;
//...do something associated with user data
return OK();
}
}
Finally make sure that the abstraction and it's implementation a registered with your dependency container in your composition root.

Related

unity resolve instance at web api controller

Is there any way to resolve the instance of a class at the controller level? I would like to override the previous instance created by unity and assign this new value via the controller.
Problem is I am not sure how to access the unity container in the web app controller.
Here is my code:
Repository:
public class UserRepository: IUserRepository
{
private UserInformation _userInfo;
public UserRepository(string headerValue)
{
_userInfo = LoadUserData(headerValue);
}
public UserInformation GetUserInfo()
{
return _userInfo;
}
}
public class UserInformation
{
public string FirstName;
public string LastName;
}
Unity Configuration:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
//Some code omitted
config.DependencyResolver = new UnityDependencyResolver(UnityConfig.RegisterComponents());
}
}
public static class UnityConfig
{
public static UnityContainer RegisterComponents()
{
//Unity Configuration
var container = new UnityContainer();
container.RegisterType<IUserRepository, UserRepository>(new InjectionConstructor("DummyHeaderValue"));
return container;
}
}
Controller:
public class CustomerController : ApiController
{
public CustomerController()
{
//Something like this
container.Resolve<UserRepository>(new InjectionConstructor(Request.GetHeader("RealHeaderValueFromHttpRequest")));
}
}
Then I should be able to use the updated UserRepository instance throughout the application.
Any thoughts on how to achieve this?
Edit: As pointed out by #Nkosi I don't have access to Request in controller constructor. So let me rephrase my question again:
How would I initialise UserRepository with UserInformation object which contains details about the current user? The reason I want to do this is that throughout my application I want user details and I don't want to pass User Id from each method
Something like this: From any method throughout application
UserInformation obj = _userRepository().GetUserInfo();
Create an abstraction to get access to the request
public interface IHeaderService {
string RealHeaderValueFromHttpRequest();
}
Its Implementation will have access to the context and request to get the desired functionality
public class HeaderService : IHeaderService {
public string RealHeaderValueFromHttpRequest() {
return HttpContext.Current.Request.Headers["RealHeaderValueFromHttpRequest"];
}
}
The service will now be explicitly injected into the dependent repository
public class UserRepository: IUserRepository {
private readonly IHeaderService headerService;
public UserRepository(IHeaderService headerService) {
this.headerService = headerService;
}
public UserInformation GetUserInfo() {
var headerValue = headerService.RealHeaderValueFromHttpRequest();
var _userInfo = LoadUserData(headerValue);
return _userInfo;
}
//...
}
The repository will then also be explicitly injected into dependent controllers.
public class CustomerController : ApiController {
private readonly IUserRepository repositoty;
public CustomerController(IUserRepository repositoty) {
this.repository = repository;
}
public IHttpActionResult SomeAction() {
//NOTE: Only access user info in a controller action
var userInfo = repository.GetUserInfo();
//... use user info.
}
//...
}
Now all that is left is to make sure all abstractions and their implementations are registered with the dependency container
public static class UnityConfig {
public static UnityContainer RegisterComponents() {
//Unity Configuration
var container = new UnityContainer();
container.RegisterType<IUserRepository, UserRepository>();
container.RegisterType<IHeaderService, HeaderService>();
return container;
}
}

How to store data in cache?

I created a ViewComponent to display a List<Product>, the list is valorized taken data from a REST API service, this is my class implementation:
public class ProductsViewComponent : ViewComponent
{
private readonly HttpClient _client;
public ProductsViewComponent(HttpClient client)
{
_client = client ?? throw new ArgumentNullException(nameof(client));
}
public async Task<IViewComponentResult> InvokeAsync(string date)
{
using (var response = await _client.GetAsync($"/"product/get_products/{date}"))
{
response.EnsureSuccessStatusCode();
var products = await response.Content.ReadAsAsync<List<Product>>();
return View(products);
}
}
}
I load the List inside an html table which is available inside the Components folder: Views\Shared\Components\Products\Default.cshtml.
In each View that needs to display the Products I did:
#await Component.InvokeAsync("Products", new { date = myDate })
The REST API is called using the HttpClient configured in the Startup.cs as following:
services.AddHttpClient<ProductsViewComponent>(c =>
{
c.BaseAddress = new Uri('https://api.myservice.com');
});
This works well, but the main problem is each time the user reload the page or maybe go inside another View which require to display the list of products, then the app will make another API call.
Is possible store the list in something like a cache and prevent to call the API again if the date is equal than the previous date selected?
I'm learning ASP.NET Core so I'm not really expert on this argument.
Thanks in advance for any help.
As per microsoft documentation https://learn.microsoft.com/en-us/aspnet/core/performance/caching/memory?view=aspnetcore-2.1
you can use IMemoryCache to cache data
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddMemoryCache();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
public void Configure(IApplicationBuilder app)
{
app.UseMvcWithDefaultRoute();
}
}
and create instance of IMemoryCache. This is an example from Microsoft documentation. You can Create another class to handle this all together and In below example this is just saving DateTime But, you can save any object in cache and when you try to read that value from cache just need to cast that object into a Type.
I will strongly recommend you go through the above documentation.
public class HomeController : Controller
{
private IMemoryCache _cache;
public HomeController(IMemoryCache memoryCache)
{
_cache = memoryCache;
}
public IActionResult CacheTryGetValueSet()
{
DateTime cacheEntry;
// Look for cache key.
if (!_cache.TryGetValue(CacheKeys.Entry, out cacheEntry))
{
// Key not in cache, so get data.
cacheEntry = DateTime.Now;
// Set cache options.
var cacheEntryOptions = new MemoryCacheEntryOptions()
// Keep in cache for this time, reset time if accessed.
.SetSlidingExpiration(TimeSpan.FromSeconds(3));
// Save data in cache.
_cache.Set(CacheKeys.Entry, cacheEntry, cacheEntryOptions);
}
return View("Cache", cacheEntry);
}
}
Update: CacheKeys.Entry is a static class where all keys are defined. (Just coding standards). Please check the above documentation link.
public static class CacheKeys
{
public static string Entry { get { return "_Entry"; } }
public static string CallbackEntry { get { return "_Callback"; } }
public static string CallbackMessage { get { return "_CallbackMessage"; } }
public static string Parent { get { return "_Parent"; } }
public static string Child { get { return "_Child"; } }
public static string DependentMessage { get { return "_DependentMessage";} }
public static string DependentCTS { get { return "_DependentCTS"; } }
public static string Ticks { get { return "_Ticks"; } }
public static string CancelMsg { get { return "_CancelMsg"; } }
public static string CancelTokenSource { get { return "_CancelTokenSource";} }
}
You can use a distributed cache and so use Redis for example with a ConnectionMultiplexer.
And so foreach call you can call your redis for the cache which is implement thanks to an interface call here 'IDistributedCache'
You can find a lot of documentation to implement cache and use it.
: .Net framework
DotNet Core
Your controller X :
[HttpGet]
[Route("{itemId}")]
public async Task<IHttpActionResult> GetItemById(int eventId, [FromUri]EventTabs tabId)
{
ServiceResponse<ItemDto> result = await _itemDispatcher.GetItemById(itemId);
return WrapResponse(result);
}
Your dispatcher to get the item by id which use redis cache (already implement)
public class ItemDispatcher : ItemDispatcher
{
private readonly IUnitOfWork _unitOfWork;
private readonly IDistributedCache _distributedCache; // use interface of your implementation of redis cache
private readonly int _cacheDuration;
private readonly bool _isCacheEnabled;
public EventDispatcher(IUnitOfWork unitOfWork, IDistributedCache distCache)
{
_unitOfWork = unitOfWork;
_distributedCache = distCache; // init cache in constructor
_cacheDuration = _configuration.Get<int>("cache.duration"); // duration of your cache
_isCacheEnabled = _configuration.Get<bool>("cache.isEnable"); // if the cache is enable or not
}
public async Task<ServiceResponse<ItemDto>> GetItemById(int id)
{
// Add this for each Task call
var cacheKey = string.Empty;
if (_isCacheEnabled)
{
cacheKey = CacheUtils.GetCacheKey(CacheKeys.Item, id);
itemDto cacheResult = await _distributedCache.Get<ItemDto>(cacheKey);
if (cacheResult != null)
return new ServiceResponse<Item>(cacheResult);
}
}
Try This
Cache["KeyName"] = VariableOrTable; Cache.Insert("Key", VariableOrTable, null,
Cache.NoAbsoluteExpiration, ts);

How to convert this static class method into a dependency injection? (Specific code included)

(I am sure that I formatted the question badly, I would be happy to revise and fix depending on comments)
I have a static class and I am trying to improve the design with dependency injection. I don't necessarily want this class to be static anymore because I will be using .NET Core, which promotes dependency injection over static class situations.
The simplified code in .NET (not Core):
public static class Utils
{
public static readonly string tokenUrl = ConfigurationManager.AppSettings["tokenUrl"];
public static readonly string tokenKey = ConfigurationManager.AppSettings["tokenKey"];
public async static Task<bool> SendEmail(Email email)
{
var http = new HttpClient();
http.DefaultRequestHeaders.Add("subscription-key", tokenKey);
try
{
await http.PostAsync(tokenUrl + "email", new StringContent(JsonConvert.SerializeObject(email), Encoding.UTF8, "application/json"));
}
catch (Exception e)
{
return false;
}
return true;
}
}
For ConfigurationManager.AppSettings (it does not exist in .NET Core), I am planning to use the method in this link: http://www.danylkoweb.com/Blog/no-configurationmanager-in-aspnet-core-GC
However, for converting this (SendMail) method into a dependency injection, I am quite lost. I have read many examples and articles and I understand the logic of dependency injection but I don't know how to convert this static class into a proper dependency injection. There are other methods in the same Utils class but this is the simplest one and I hope to figure out the others using this one.
An approach that I was thinking off was:
public interface ISendMail
{
FormSettings ConfigSettings { get; set; }
Task<bool> SendEmail(IOptions<FormSettings> settings, Email email);
}
and:
public class SendEmail : ISendMail
{
public async static Task<bool> SendEmail(IOptions<FormSettings> settings, Email email)
{
//do same things
}
}
but I am CLEARLY lost with this because it does not even make sense. Another approach that I was thinking of was:
public class SendEmail
{
FormSettings ConfigSettings { get; set; }
protected Email email = null;
public SendEmail(IOptions<FormSettings> settings, Email email)
{
ConfigSettings = settings.Value;
this.email = email;
}
public async static Task<bool> SendEmailAction()
{
//do same things with "email" and "ConfigSettings"
}
}
I know I am giving a lot of code here and I wasn't sure if I should ask about this in "Code Review" or something. My biggest concern is not the FormSettings part but implementing the functionality of SendEmail in a dependency injection format.
Shortly, how can I convert this "SendEmail" class into a format where I can use it with .NET Core, without having a static class? This particular method does not require change with .NET Core but my other methods do, that is why I am trying to get rid of the static class approach.
I can exclude the tokenUrl and tokenKey parts and simplify the problem if requested, I am just quite lost as to how to approach this situation.
What should do this class? Sending email, right? So interface:
public interface IEmailSender
{
Task<bool> Send(Email email);
}
How we can implement it? Like this:
public class MyEmailSenderOne : IEmailSender
{
public static readonly string tokenUrl = ConfigurationManager.AppSettings["tokenUrl"];
public static readonly string tokenKey = ConfigurationManager.AppSettings["tokenKey"];
public async Task<bool> Send(Email email)
{
var http = new HttpClient();
http.DefaultRequestHeaders.Add("subscription-key", tokenKey);
try
{
await http.PostAsync(tokenUrl + "email", new StringContent(JsonConvert.SerializeObject(email), Encoding.UTF8, "application/json"));
}
catch (Exception e)
{
return false;
}
return true;
}
}
or
public class MyAnotherAwesomeEmailSender : IEmailSender
{
public async Task<bool> Send(Email email)
{
// send with different way
return true;
}
}
How we can inject this?
public class SomeClass
{
private IEmailSender _sender;
public SomeClass(IEmailSender sender)
{
_sender = sender;
}
public void Foo()
{
// do smth useful
_sender.Send(new Email());
}
}
UPD.
Because your email settings persistant (will not change during lifetime), and because this settings related ONLY to your implementation of IEMailSender, you should to inject them in your implementation. Just think about = why caller code (Controller) should know about how your implementation works?
So
public class MyEmailSenderOne : IEmailSender
{
private FormSettings _settings;
public MyEmailSenderOne(IOptions<FormSettings> settings)
{
_settings = settings.Value;
}
public async Task<bool> Send(Email email)
{
var http = new HttpClient();
http.DefaultRequestHeaders.Add("subscription-key", _settings.tokenApiKey);
try
{
await http.PostAsync(_settings.tokenApiUrl + "email", new StringContent(JsonConvert.SerializeObject(email), Encoding.UTF8, "application/json"));
}
catch (Exception e)
{
return false;
}
return true;
}
}
And, controller now dint know about any settings for your implementation, and it looks like
public class CommunicationsController : Controller
{
private IEmailSender _sender;
public CommunicationsController(IEmailSender sender)
{
_sender = sender;
}
public async Task<ActionResult> ContactUsFormSubmit(ContactUs request)
{
...
request.EmailSent = await _sender.SendEmail(new Email() { TemplateId = 3, Body = JsonConvert.SerializeObject(request) });
...
}
}
As you can see, controller is very clean now and you can easily change your implementation of IEmailSender to any other without changing Controller code. This is one of advantages of using DI.
Based on tym32167's answer, I was able to implement the IEmailSender functionality (finally). I will still choose his answer as the correct answer but this is how I implemented dependency injection.
Please read the link I provided in the question, if you'd like to know more about the IOptions and FormSettings class that I am using.
Here is the interface and the class:
public interface IEmailSender
{
Task<bool> SendEmail(Email email, FormSettings settings);
}
public class EmailSender : IEmailSender
{
FormSettings ConfigSettings { get; set; }
public async Task<bool> SendEmail(Email email, FormSettings settings)
{
var http = new HttpClient();
http.DefaultRequestHeaders.Add("subscription-key", settings.tokenApiKey);
try
{
await http.PostAsync(settings.tokenApiUrl + "email", new StringContent(JsonConvert.SerializeObject(email), Encoding.UTF8, "application/json"));
}
catch (Exception e)
{
return false;
}
return true;
}
}
In controller injection:
public class CommunicationsController : Controller
{
private IEmailSender _sender;
private FormSettings ConfigSettings { get; set; }
public CommunicationsController(IEmailSender sender, IOptions<FormSettings> settings)
{
_sender = sender;
ConfigSettings = settings.Value;
}
public async Task<ActionResult> ContactUsFormSubmit(ContactUs request)
{
...
request.EmailSent = await _sender.SendEmail(new Email() { TemplateId = 3, Body = JsonConvert.SerializeObject(request) }, ConfigSettings);
...
}
Here is FormSettings just for easy reference in case the link dies:
public class FormSettings
{
public string tokenApiUrl { get; set; }
public string tokenApiKey { get; set; }
}
I hope I didn't miss any details, so far it didn't give me any errors but since we do not have unit testing in the project, I won't be able to test immediately. Please let me know if there is something missing with the answer.

How should be information about logged in user passed to repository in ASP.NET MVC?

What is the best way of passing user information if items in database are assigned to specific users and no user can get access to data which isn't his? I have two ideas, but I don't know if any of them is correct.
First idea I don't like, because it requires to pass user name every time I want to get any data from repository:
public class Repository : IRepository
{
private DbContext dbContext = new DbContext();
public IEnumerable<Item> GetItems(string userName)
{
return dbContext.Items.Where(i => i.UserName == userName);
}
}
Second is injecting user name and it looks more natural to me, because I can use repository like there was no user authentication, but I have no idea if it's safe and if it's ASP.NET MVC style:
public class Repository : IRepository
{
private DbContext dbContext = new DbContext();
private string userName;
public Repository(string userName)
{
this.userName = userName;
}
public IEnumerable<Item> Items
{
get { return dbContext.Items.Where(i => i.UserName == userName); }
}
}
// In NinjectDependencyResolver.cs:
public void AddBindings()
{
kernel.Bind<IRepository>().To<Repository>().WithConstructorArgument(HttpContext.Current.User.Identity.Name);
}
I don't know if it's good to use HttpContext class somewhere else than controller or view.
These are very simple examples and I didn't compile them, but I hope there's no mistakes and you know what I mean. Of course UserName should be part of another table with users, but I made it as simple as I could.
public ItemsController : Controller {
private readonly IItemsService _service;
public ItemsController(IItemsService service) {
_service = service;
}
public ActionResult Index(){
return View("Index", _service.GetItemsForUser(HttpContext.Current.User.Identity.Name));
}
}
your service would look like this
public class ItemsService : IItemsService {
private readonly IItemsRepository _repository;
public ItemsService(IItemsRepository repository) {
_repository = repository;
}
public IEnumerable<Item> GetItemsForUser(string username) {
return _repository.GetItems(username);
}
}
and you repo
public ItemsRepository : IItemsRepository, IRepository {
private DbContext dbContext = new DbContext();
public ItemsRepository() {
}
public IEnumerable<Item> GetItems(string username) {
return _context.Items.Where(i => i.username == username).ToList();
}
}
or something similar to this structure. I have used interfaces because I assume the use of inversion of control.

Ninject: entity object cannot be referenced by multiple instances of IEntityChangeTracker

I am starting to use Ninject in my MVC5 code-first app. Here's my NinjectWebCommon.cs:
private static IKernel CreateKernel()
{
var kernel = new StandardKernel();
try
{
kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
kernel.Bind<CMSContext>()
.ToSelf()
//.InSingletonScope();
.InRequestScope();
kernel.Bind<IExecutiveRepository>()
.To<ExecutiveRepository>();
kernel.Bind<IExecutiveSectionRepository>()
.To<ExecutiveSectionRepository>();
kernel.Bind<IExecutiveSectionMappingRepository>()
.To<ExecutiveSectionMappingRepository>();
kernel.Bind<IUserRepository>()
.To<UserRepository>();
kernel.Bind<IContentRepository>()
.To<ContentRepository>();
RegisterServices(kernel);
return kernel;
}
catch
{
kernel.Dispose();
throw;
}
}
I tried .InSingletonScope() as well as .InRequestScope() but I still get the 'entity object cannot be referenced by multiple instances of IEntityChangeTracker' error.
Here is my Interface:
public interface IExecutiveRepository : IDisposable
{
IEnumerable<Executive> GetExecutives();
Executive GetExecutiveById(int executiveId);
void InsertExecutive(Executive executive);
void UpdateExecutive(Executive executive);
void DeleteExecutive(int executiveId);
void Save();
}
Here is my concrete:
public class ExecutiveRepository : IExecutiveRepository, IDisposable
{
private CMSContext context;
public ExecutiveRepository(CMSContext context)
{
this.context = context;
}
public IEnumerable<Executive> GetExecutives()
{
return context.Executives.ToList();
}
public Executive GetExecutiveById(int id)
{
return context.Executives.Find(id);
}
public void InsertExecutive(Executive executive)
{
context.Executives.Add(executive);
}
public void DeleteExecutive(int executiveId)
{
Executive executive = context.Executives.Find(executiveId);
context.Executives.Remove(executive);
}
public void UpdateExecutive(Executive executive)
{
context.Entry(executive).State = EntityState.Modified;
}
public void Save()
{
context.SaveChanges();
}
private bool disposed = false;
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
context.Dispose();
}
}
this.disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
Here is the controller(top pertinent part):
public class ExecutiveController : Controller
{
private IExecutiveRepository executiveRepository;
private IUserRepository userRepository;
private IExecutiveSectionRepository executiveSectionRepository;
private IExecutiveSectionMappingRepository executiveSectionMappingRepository;
private IContentRepository contentRepository;
private Ninject.IKernel _kernel = new StandardKernel();
//[Inject]
public ExecutiveController()
{
executiveRepository = _kernel.Get<ExecutiveRepository>();
userRepository = _kernel.Get<UserRepository>();
executiveSectionRepository = _kernel.Get<ExecutiveSectionRepository>();
executiveSectionMappingRepository = _kernel.Get<ExecutiveSectionMappingRepository>();
contentRepository = _kernel.Get<ContentRepository>();
}
...
Not sure what I am doing wrong but upon adding a new 'Executive' it bombs... I do understand it's trying to use separate contexts and that's the problem, but I 'm just not sure how to fix it. Apparently, the line in the NinjectWebCommon.cs class:
kernel.Bind<CMSContext>()
.ToSelf()
//.InSingletonScope();
.InRequestScope();
Is supposed to be the fix, but it isn't...
any ideas/suggestions?
You should be using NUGET package Ninject.Web.Mvc if you aren't already. This configures your application ready to use Ninject, other than your bindings. It looks like you are reasonably familiar with the bindings side of things already from what I can see in your CreateKernel() method.
Once your bindings are in place, you should not be creating Kernels in your controllers, this is because the Ninject.Web.Mvc library configures Ninject to create your controllers for you under the hood. Therefore any dependencies that you add to them should be automatically resolved.
So, you can use constructor injection to resolve your dependencies:
public class ExecutiveController : Controller
{
private IExecutiveRepository ExecutiveRepository;
private IUserRepository UserRepository;
private IExecutiveSectionRepository ExecutiveSectionRepository;
private IExecutiveSectionMappingRepository ExecutiveSectionMappingRepository;
private IContentRepository ContentRepository;
public ExecutiveController(
IExecutiveRepository executiveRepository,
IUserRepository userRepository,
IExecutiveSectionRepository executiveSectionRepository,
IExecutiveSectionMappingRepository executiveSectionMappingRepository,
IContentRepository contentRepository)
{
// Set the field values
this.ExecutiveRepository = executiveRepository,
this.UserRepository = userRepository,
this.ExecutiveSectionRepository = executiveSectionRepository,
this.ExecutiveSectionMappingRepository = executiveSectionMappingRepository,
this.ContentRepository = contentRepository;
}
public ActionResult Index(int id)
{
// Use one of your dependencies...
var executive = this.executiveRepository.GetExecutiveById(id);
}
}
Or you can use the [Inject] attribute which has the same effect:
public class ExecutiveController : Controller
{
[Inject]
public IExecutiveRepository executiveRepository { get; set; }
[Inject]
public IUserRepository userRepository { get; set; }
[Inject]
public IExecutiveSectionRepository executiveSectionRepository { get; set; }
[Inject]
public IExecutiveSectionMappingRepository executiveSectionMappingRepository { get; set; }
[Inject]
public IContentRepository contentRepository { get; set; }
public ExecutiveController()
{
}
public ActionResult Index(int id)
{
// Use one of your dependencies...
var executive = this.executiveRepository.GetExecutiveById(id);
}
}
You're creating a kernel per controller.
InRequestScope only ensures one instance per request per kernel.
So you need to adapt your setup of the kernel so there's only one kernel per web application. See:
Ninject.Web.Mvc
Tutorial
Youtube
This may not answer the question. But I tend to use the IDbContextFactory that EF provides you with and do something like this:
public interface IDefaultContextFactory : IDbContextFactory<CMSContext> {}
public class DefaultContextFactory : IDefaultContextFactory
{
private readonly Lazy<CMSContext> lazyContext = new Lazy<CMSContext>(() => new CMSContext());
public CMSContext Create()
{
return lazyContext.Value;
}
}
Then you just bind that, and when you need the context you can do something like this:
public class ExecutiveRepository : IExecutiveRepository, IDisposable
{
private readonly CMSContext context;
public ExecutiveRepository(IDefaultContextFactory contextFactory)
{
this.context = contextFactory.Create();
}
}
I believe #BatteryBackupUnit is correct, I would also consider using the above pattern for contexts.

Categories