In an ASP.NET MVC 3 Web Role, I have realized that I have been writing the below code a lot:
var account =
CloudStorageAccount.Parse(
RoleEnvironment.GetConfigurationSettingValue("DataConnectionString")
);
var ctx =
account.CreateCloudTableClient().GetDataServiceContext();
So, I decided to Centralize this for the entire ASP.NET MVC application and I created the below class with static properties:
internal class WindowsAzureStorageContext {
public static CloudStorageAccount StorageAccount {
get {
return
CloudStorageAccount.Parse(
RoleEnvironment.GetConfigurationSettingValue("DataConnectionString")
);
}
}
public static TableServiceContext TableServiceCtx {
get {
return
StorageAccount.CreateCloudTableClient().GetDataServiceContext();
}
}
}
And, I am using this as below inside my controllers:
public class HomeController : Controller {
private readonly TableServiceContext ctx =
WindowsAzureStorageContext.TableServiceCtx;
public ViewResult Index() {
var model = ctx.CreateQuery<TaskEntity>(Constants.TASKS_TABLE).
Where(x => x.PartitionKey == string.Empty);
return View(model);
}
public ViewResult Create() {
return View();
}
[ActionName("Create")]
[HttpPost, ValidateAntiForgeryToken]
public ViewResult Create_post(TaskEntity taskEntity) {
ctx.AddObject(Constants.TASKS_TABLE, new TaskEntity(taskEntity.Task));
ctx.SaveChangesWithRetries();
return RedirectToAction("Index");
}
}
I know that this is not a unit test friendly and I should reach out that TableServiceContext instance through a interface by DI but when I do that, I consider using this WindowsAzureStorageContext class as well to get an instance of TableServiceContext class.
Is this a good practice? Would it hurt me in any point because I am using the same class for the entire application life-cycle?
Is there any know pattern to do this?
I don't see any problem with doing that. Looks like a nice clean way to do it. I don't know of a known pattern to do this but was just thinking there should be yesterday.
I think you can use repository pattern for a generic data context, with a generic interface on top of it. Not sure if it helps but you can refer my blog http://blogs.shaunxu.me/archive/2010/03/15/azure-ndash-part-5-ndash-repository-pattern-for-table-service.aspx
I don't believe that there is any shared state between instances of the context. With that said, the transaction time for the controller to execute is non-trivial. The longer you hold onto the context, the more likely you are to get conflicts. I've found that one way to keep conflicts and overlaps to a minimum is to keep the load/change/save cycle as short as possible.
Erick
Related
First, let me explain breafly what I have, what I want to achieve, how I did it so far, and why I'd like to improve my current implementation.
WHAT I HAVE
Basically, I have a .NET Core project that runs an API Service with some APIs.
Also, I have a class called MyFundamentalClass, which is used throughout the whole application: in fact, MyFundamentalClass implements the Singleton Pattern, having something like this:
public class MyFundamentalClass {
private static _myFundamentalClass = null;
public static MyFundamentalClass GetInstance() {
if (_myFundamentalClass == null)
_myFundamentalClass = new MyFundametalClass();
return _myFundamentalClass;
}
}
Reason why I want this Singleton Pattern is that this class is used in many occasion in the whole project; the alternative would be to instantiate the class in the ControllerAction, and then pass it basically EVERYWHERE: it's not sustainable.
THE PROBLEM
As you can imagine, here was the first problem: each request MUST HAVE its own instance of MyFundamentalClass. As you can imagine, static keyword does not work very well with that.
Why I'm telling this: if I want an instance of MyFundamentalClass in each ControllerAction, I should write something like this:
public async Task<ActionResult> GetUserData() {
MyFundamentalClass = new MyFundamentalClass();
return await MyFundametalClass.GetUserData();
}
So far so good, but as I said, I need the Singleton Pattern, so I should change the code into:
public async Task<ActionResult> GetUserData() {
MyFundamentalClass = MyFundamentalClass.GetInstance();
return await MyFundametalClass.GetUserData();
}
What's the problem? Two different API calls will overwrite the private field MyFundamentalClass._myFundamentalClass, mixing the context of the two API. HUGE PROBLEM!
MY CURRENT SOLUTION
What I found , the only way, was the use of AsyncLocal<MyFundamentalClass>. I've something like this:
public class RequestContext {
publicv static AsyncLocal<MyFundamentalClass> Instance = new AsyncLocal<MyFundamentalClass>(null);
}
// Then, in each ControllerAction
public async Task<ActionResult> GetUserData() {
var method = async () => {
RequestContext.Instance.Value = new MyFundamentalClass();
// Whatever I need to do
}
}
// Then, in the MyFundamentalClass
public MyFundamentalClass {
public MyFundamentalClass GetInstance() {
return RequestContext.Instance.Value;
}
}
With this solution, since the AsyncLocal context lives only thourghout the async context, it perfectly fits my need.
Though, why am I searching for something else? Because I feel like I am missusing the Dependency Injection and the whole ServiceProvider stuffs.
WHAT I AM LOOKING FOR
So.. I also come upon the services.AddScoped<MyFundamentalClass>() code (Link to Microsfot DOC).
By what it tells, it should perfectly fit my need: what is created by that AddScoped lives only for the API -> one API one instance.
But, problem is: how could I exploit the instance created by AddScoped with the Singleton Pattern?
I know that, with DependencyInject, in my Controller I can add the object in the constructor:
public class MyController : ControllerBase {
private MyFundamentalClass _myFundamentalClass;
public MyController(MyFundamentalClass myFundamentalClass) {
_myFundamentalClass = myFundamentalClass;
}
public async Task<ActionResult> GetUserData() {
return await _myFundamentalClass.GetUserData();
}
}
That feels much more correct, from a code point of view, but.. I don't have the SingletonPattern anymore, unless I still use the AsyncContext.
What I thought it was possible was to use:
public static IServiceProvider ServiceProvider;
public static WorkbenchViewModel GetInstance() {
ServiceProvider.GetService(typeof(WorkbenchViewModel));
}
But I have the same problem: each request has its own IServiceProvider, thus different API would override the value.
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've been using Dependency Injection in ASP.NET MVC the way I've explained in the below code, but I'm not sure if that is the right and standard way to do it. So I just wanna know if what I'm doing is wrong or if there is a better and more professional way to do it.
public interface IService {
public Boolean AddRecord(Object _Model);
}
public class Employee: IService {
DataBase Context = new DataBase();
public Boolean AddRecord(Object _Model) {
Context.Add((EmployeeModel) _Model);
return Context.SaveChanges() != 0;
}
}
public class DataController: Controller {
IService service;
public DataController(IService service) {
this.service = service;
}
public ActionResult AddRecord(Object _Model, String Caller) {
if (service.Add(_Model)) {
TempData["Result"] = "Data Added";
return RedirectToAction(Caller);
}
TempData["Result"] = "Please try again";
return View (Caller, _Model);
}
}
When I wanna use the controller with the DI, I do: (Is this the right way to consume the DataController)
public class TestController: Controller {
public ActionResult Index () {
return View();
}
public ActionResult TestIt (EmployeeModel _Model) {
DataController DC = new DataController(new Employee());
return DC.AddRecord(_Model, "../Test/TestIt");
}
}
You have the general concept of Dependency Injection / Inversion down. That is, you've understood that instead of this:
public class Example {
public void SomeFunc() {
var service = new Service();
service.DoStuff();
}
}
..you do this:
public class Example {
private readonly IService _service;
public Example(IService service) {
_service = service;
}
public void SomeFunc() {
_service.DoStuff();
}
}
.. and you supply the dependency manually via the calling code.. such as a Controller:
public HomeController : Controller {
[HttpGet]
public ActionResult Index() {
var example = new Example(new Service());
example.SomeFunc();
// .. the rest ..
}
}
So, the first part is Dependency Inversion. You have inverted the dependency chain from being top down to bottom up. The second part (the above code block) is Dependency Injection.
Notice in the above block of code that the Controller has no dependencies injected. This is where Inversion of Control comes in.
Inversion of Control is a pattern where code completely external to the currently running code decides how it functions. In this context, it means some external code - somewhere else - decides how to supply dependencies to your controller.
(Note, I am quite familiar with Ninject - so the below examples are using Ninject. There are plenty of other available DI/IoC containers available)
Ninject is a framework that can help with this (and many others). Ninject has an extension for ASP.NET MVC which automatically builds and supplies controller instances for you - plus your dependencies.
Without providing a full tutorial on using Ninject (which I will leave as an exercise to the OP to Google), the basics of it is this.
You declare a "module" with the configuration for your dependencies. Using the above examples, your module might look like this:
public class YourModule : NinjectModule {
public override void Load() {
Bind<IExample>().To<Example>().InRequestScope();
Bind<IService>().To<Service>().InRequestScope();
}
}
This will wire up all requests for an IExample to an Example, and IService to an instance of a Service. So your Controller would become:
public class HomeController : Controller {
private readonly IExample _example;
public HomeController(IExample example) {
_example = example;
}
[HttpGet]
public ActionResult Index() {
_example.SomeFunc();
// .. the rest ..
}
}
The container (in this case, Ninject) looks at your external code (the YourModule class) and determines what IExample should be. It sees that you've said it should be an instance of an Example class. Example also requires a dependency of type IService. So Ninject will again look at YourModule and determines that it should be an instance of Service. It continues to go down the object hierarchy until it completes the construction of the objects.
Hopefully that makes sense - it is definitely hard to explain these concepts in text.
I haven't viewed this video (I am running off of really really terrible WiFi hotspot while I wait for an internet connection!) so I can't verify it's quality, but a quick Google search turned this up for setting up Ninject and MVC: http://www.youtube.com/watch?v=w_MehI2qBTo
You would definitely benefit from Googling around some Inversion of Control and/or Ninject videos to understand what frameworks like it are for.
It is important to note too that frameworks like Ninject can also control scope. In the example above, I used InRequestScope against the bindings. This means that Ninject will instantiate the dependency at the start of the web request - and dispose of it afterward. This removes the need for you to worry about that.
I have a Windows authenticated MVC application with a repository layer. All interaction by the controller with the database is done through the repository. Each controller has a reference to the repository:
public class PostController : Controller
{
private Repository db = new Repository();
[HttpPost]
public ActionResult DeletePost(int id)
{
// Authorize that the user is allowed to delete this post...
db.DeletePost(id);
}
}
My question is whether there is a good way to move my authorization logic into the repository layer. I'd like the Repository.DeletePost() function to refuse to delete posts that were not created by the authenticated user. The problem is that my repository does not know who the authenticated user is. The controller knows (via Controller.User).
Passing the Controller.User into the Repository constructor doesn't work, because the Controller.User is apparently not defined at the time when the constructor is called.
How can I inform the Repository of who the authenticated user is? Would it be best to just construct the Repository within each action? Or is it a bad idea to handle it in the repository layer?
Or is it a bad idea to handle it in the repository layer?
I think the Controller is a better place for your authorization. Let the repository be a gateway to the data and the controller be a gatekeeper to your application. I'd expect to see authorization/authentication logic as early in the life-cycle as possible.
Just do something like:
db.DeletePostForUser(id, User.Identity.UserId);
Then in your repository:
public void DeletePostForUser(int id, int userId)
{
var post = context.Posts.SingleOrDefault(m => m.PostId == id && m.User.UserId == userId)
if (post != null)
{
context.Posts.Remove(post);
context.SaveChanges();
}
}
Good suggestions from both #BigDaddy and #ChrisPratt.
I ended up solving this by creating a base controller, similar to this answer. My base controller class looks like:
public class BaseController : Controller
{
private ILog _log;
private Repository _db;
protected Repository Db
{
get
{
return _db ?? (_db = new Repository(User));
}
}
protected ILog Log
{
get
{
return _log ?? (_log = LogManager.GetLogger(this.GetType()));
}
}
}
All of my controllers inherit from this class, and have built-in access to a lazy-loaded Repository that has a reference to the currently authenticated user.
in a typical MVC3 app with an EF model, each controller instantiates its own copy of the model container. this means that if I were to create a class in a different file and it needed access to the model, it would need to instantiate its own container.
Consider the following:
namespace X.Web.Controllers
{
public class TestController : Controller
{
EFContainer db = new EFContainer();
public ActionResult Whatever()
{
User u = db.Users.Find(3);
...
}
if I wanted to abstract my fetching of a user in a class Auth then it would have to instantiate its own db since it doesn't have access to the controller's -- all fine until the controller wants to make changes to the returned object:
public ActionResult Whatever()
{
User u = Auth.GetUser();
u.Name = "ekkis";
db.SaveChanges();
...
}
since the user at that point belongs to a different context... so either I have to share my db with Auth or perhaps I'd have to do a moronic double-lookup:
public ActionResult Whatever()
{
int id = Auth.GetUserId();
User u = db.Users.Find(id);
u.Name = "ekkis";
db.SaveChanges();
...
}
what is the recommended way of dealing with this?
Why don't you pass in your model / EF context via constructor injection into your Auth class? That seems to be the most reasonable way (same applies to your controller actually once you have an IOC container set up).
public class Auth
{
public Auth(EFContainer db)
{
//...
}
}
Ideally you would also make this work based on an abstract interface so you can test Auth independently of EF.