mvc3 and linq to sql architecture - asp.net-mvc-3

I am building an MVC3 application and I am using Linq to sql for my DAL. My DAL is called MyDataReader and handles creating/initializing datacontext, plus it defines all the methods that retrieve data from the database. All the methods are instance methods, so in order to call the methods, I need to instantiate a MyDataReader object.
My questions is: what is the best way to call the methods in my DAL. Initially, I was instantiating a MyDataReader object from the controllers whenever I needed to call a DAL method. Then I realized every time I instantiate a MyDataReader object, the datacontext object is created and a connection gets established.
In my second approach, I created a static parameter in the Global.asax file as:
public class MvcApplication : System.Web.HttpApplication
{
public static MyDataReader reader;
protected void Application_Start()
{
reader = new MyDataReader();
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}
}
This limits the database initialization operation to minimum. I can call the DAL methods from all my controllers by:
MvcApplication.reader.CallTheMethod()
Is this a good way? What is the best way to call DAL methods?

No, this is the absolute worst way to do it. The biggest reason is that static objects are shared between all concurrent users. That means multiple users adding, removing, querying the same context. This is a recipe for disaster, and will probably cause data corruption.
The other problem is that data contexts are designed to be short lived, so they do not manage their internal caches and lists, they just assume you will dispose of them when you are done with an operation.
You do not need to worry about connection management. Internally, this is managed in a connection pool, and .net will automatically reuse connections and dispose of them when they are idle for a period of time.
Don't pre-maturely optimize. You are usually wrong.

Related

Good usage of managed entities / proxies with ORM

I'm currently thinking about how i handle my domain objects along with hibernate considering the following :
My model object are directly annotated with JPA annotation, no entity layer.
On some database heavy operation, i don't mind tuning my code so i take full advantages of the proxies, even if we can consider it as a leak of abstraction/implementation masking. Of course i prefer when i can do otherwise.
Because i don't have entity layer, i don't have a DAO layer, the entity manager is considerered itself as a DAO layer (related : I found JPA, or alike, don't encourage DAO pattern)
However i was thinking about improve what i'm doing know in order to reduce a bit the complexity, or at least, relocate that complexity in a place it fits better, like entity's related service. And maybe more abstract the fact that i'm using an ORM.
Here is a generic CRUD Service from which all my business service inherits. This code is to show you how things are done currently (annotation, logs remove for clarity) :
public void create(T entity) {
this.entityManager.persist(entity);
}
#Transactional(value = TxType.REQUIRED, rollbackOn=NumeroVersionException.class)
public void update(T entity) throws NumeroVersionException{
try{
this.entityManager.merge(entity);
}catch(OptimisticLockException ole){
throw new NumeroVersionException("for entity "+entity, ole);
}
}
public T read(int id) {
return this.entityManager.find(entityClass, id);
}
public void delete(int id) {
T entity = this.entityManager.getReference(entityClass, id);
this.entityManager.remove(entity);
// edit : removed null test thanks to #JBNizet
}
The problem with this kind of implementation, is that if i want to create an object, then use the advantages of the proxies i basically have to create it then refetch it. Of course the query may not hits the database but hits only hibernat's cache (not sure about it though). But that means i still have to not forget to refetch the proxy.
This mean i leak the fact that i'm using an ORM and proxies behind the scenes.
So i was thinking to change my interface to something like :
public T read(int id);
public T update(T t)throws NumeroVersionException;
public T create(T object);
public void delete(int id);
List<T> list();
Meaning once i pass an object to this layer, i will have to use the returned value.
And implements update specifically like :
public T update(T t){
if(!(t instanceof [Proxy class goes there])){
//+ check if it is a detached proxy
entityManager.merge(t);
}
}
Since merge hits the database every time called, for some operation involving just some 10ish entities this can be annoying i wouldn't call it in an update method with a proxy.
Of course I expect to have some edge cases where i'll need the entityManager to flush things and so on. But i think this would reduce significatively the current complexity of my code and isolate better the concerns.
What i'm trying in short is to relocate the ORM code within the service so i can hide the fact that i'm using an ORM and proxies and use the interface like i was using any other implementation without loosing the benefits of using an ORM.
The question is so :
Is that new design a good idea towards this idea ?
Did i miss anything about how to handle this properly ?
Note : Even though i'm talking about performance, my concern is also about isolation of concerns, maintenability, and easier usability for developers that aren't familiars with ORMs and Java which i work with.
Thanks to #JBNizet i'm seeing some thing more clearly :
I should use the value returned by merge() method.
A managed entity is not always a proxy.
I don't have to abstract the fact that i use managed entities, this will lead to complex and unefficient code
I choosed JPA i won't switch for it which is true unless rewriting the full model to stand for something based on non relationnal database.
So i'll just change my update method from the original code and i'll keep the rest.

Is there any way to intercept all Linq to SQL queries?

I've built some code that can rebuild expression trees so I can avoid triggering the no supported translation to SQL exception and it works fine as long as I call my function to replace the iqueryable. The problem is that I'd like it to automatically be applied to all queries in my project without having to worry about calling this function on each one separately. Is there any way that I can intercept everything?
I've tried using Reflection.Emit to create a wrapping provider and using reflection to replace it on the data context and it turns out that even with Reflection.Emit I can't implement the internal IProvider interface.
I've also tried replacing the provider with a RealProxy based class and that works for non-compiled queries, but the CompiledQuery.Execute method is throwing an exception because it won't cast to the SqlProvider class. I tried replacing the response to the Compile method on the provider with another proxy so I could intercept the Execute call, but that failed a check on the return type being correct.
I'm open to any other ideas or ways of using what I've already tried?
It's hard to tell whether this is an applicable solution without seeing your code, but if you have a DI-friendly app architecture you can implement an interceptor and have your favorite IoC container emit the appropriate type for you, at run-time.
Esoteric? A little. Consider an interface like this:
public interface ISomeService
{
IEnumerable<SomeEntity> GetSomeEntities();
// ...
}
This interface might be implemented like this:
public class SomeService : ISomeService
{
private readonly DbContext _context // this is a dependency!
private readonly IQueryTweaker _tweaker; // this is a dependency!
public SomeService(DbContext context, IQueryTweaker tweaker) // this is constructor injection!
{
_context = context;
_tweaker = tweaker;
}
public IEnumerable<SomeEntity> GetSomeEntities()
{
return _tweaker.TweakTheQuery(_context.SomeEntities).ToList();
}
}
Every time you implement a method of the ISomeService interface, there's always a call to _tweaker.TweakTheQuery() that wraps the IQueryable, and that not only gets boring, it also feels like something is missing a feature - the same feeling you'd get by wrapping every one of these calls inside a try/catch block, or if you're familiar with MVVM in WPF, by raising this annoying PropertyChanged event for every single property setter in your ViewModel.
With DI Interception, you factor this requirement out of your "normal" code and into an "interceptor": you basically tell the IoC container that instead of binding ISomeService directly to the SomeService implementation, you're going to be decorating it with an interceptor, and emit another type, perhaps SomeInterceptedService (the name is irrelevant, the actual type only exists at run-time) which "injects" the desired behavior into the desired methods. Simple? Not exactly.
If you haven't designed your code with DI in mind (are your dependencies "injected" into your classes' constructor?), it could mean a major refactoring.
The first step breaks your code: remove the IQueryTweaker dependency and all the TweakTheQuery calls from all ISomeService implementations, to make them look like this - notice the virtualness of the method to be intercepted:
public class SomeService : ISomeService
{
private readonly DbContext _context
public SomeService(DbContext context)
{
_context = context;
}
public virtual IEnumerable<SomeEntity> GetSomeEntities()
{
return _context.SomeEntities.ToList();
}
}
The next step is to configure the IoC container so that it knows to inject the SomeService implementation whenever a type's constructor requires an ISomeService:
_kernel.Bind<ISomeService>().To<SomeService>();
At that point you're ready to configure the interception - if using Ninject this could help.
But before jumping into that rabbit's hole you should read this article which shows how decorator and interceptor are related.
The key point is, you're not intercepting anything that's internal to LINQ to SQL or the .NET framework itself - you're intercepting your own method calls, wrapping them with your own code, and with a little bit of help from any decent IoC container, you'll be intercepting the calls to methods that call upon Linq to SQL, rather than the direct calls to Linq to SQL itself. Essentially the IQueryTweaker dependency becomes a dependency of your interceptor class, and you'll only code its usage once.
An interesting thing about DI interception, is that interceptors can be combined, so you can have a ExecutionTimerServiceInterceptor on top of a AuditServiceInterceptor, on top of a CircuitBreakerServiceInterceptor... and the best part is that you can configure your IoC container so that you can completely forget it exists and, as you add more service classes to the application, all you need to do is follow a naming convention you've defined and voilĂ , you've just written a service that not only accomplishes all the strictly data-related tasks you've just coded, but also a service that will disable itself for 3 minutes if the database server is down, and will remain disabled until it's back up; that service also logs all inserts, updates and deletes, and stores its execution time in a database for performance analysis. The term automagical seems appropriate.
This technique - interception - can be used to address cross-cutting concerns; another way to address those is through AOP, although some articles (and Mark Seeman's excellent Dependency Injection in .NET) clearly demonstrate how AOP frameworks are a less ideal solution over DI interception.

NHIbernate SessionFactory and Configuration Recreation

I have one difficult situation.
As we know NH SessionFactory is a singleton in our app.
"Heavyweight, thread-safe, and you only should ever have one per
database".
And SessionFactory is created from Configuration().BuildSessionFactory() where Configuration() is my fluently configured database.
Here is the poblem.
I need to use different users for my connection string in an MVC app. This is needed to connect to the database by different users. When connection is ok, then I use NH to manipulate domain mapped objects.
Question here is how to pass different users to Configuration and use this SessionFactory in case when we need create Configuration first of all? Creating the SessionFactory again is a wrong way, right?
And this becomes more harder because I use Windsor container to register all objects before my MVC app's run.
It sounds like you are wanting to provide a different connection string for different users of your application.
NHibernate has a feature in which you can provide your own DriverConnectionProvider which will allow you to ultimately be able to create custom connection strings on the fly by overriding the GetConnection() method.
Example:
class DynamicConnectionProvider : DriverConnectionProvider
{
public override IDbConnection GetConnection()
{
IDbConnection connection = Driver.CreateConnection();
try
{
connection.ConnectionString = // Add your logic for dynamically creating a connection string
connection.Open();
}
catch ( Exception e )
{
connection.Dispose();
throw;
}
return connection;
}
}
You can also take a look at the following links for examples:
https://stackoverflow.com/a/2927967/670028
http://nhforge.org/blogs/nhibernate/archive/2008/09/18/extending-nhibernate-s-driverconnectionprovider.aspx
And yes, creating duplicate SessionFactories would be quite costly to your applications memory usage, would complicate your applications architecture, and is really unnecessary as there are other options such as the one I listed above.

Where to put my queries - model vs. controller

I just switched from ActiveRecord/NHibernate to Dapper. Previously, I had all of my queries in my controllers. However, some properties which were convenient to implement on my models (such as summaries/sums/totals/averages), I could calculate by iterating over instance variables (collections) in my model.
To be specific, my Project has a notion of AppSessions, and I can calculate the total number of sessions, plus the average session length, by iterating over someProject.AppSessions.
Now that I'm in Dapper, this seems confused: my controller methods now make queries to the database via Dapper (which seems okay), but my model class also makes queries to the database via Dapper (which seems strange).
TLDR: Should the DB access go in my model, or controller, or both? It seems that both is not correct, and I would like to limit it to one "layer" so that changing DB access style later doesn't impact too much.
You should consider using a repository pattern:
With repositories, all of the database queries are encapsulated within a repository which is exposed through public interface, for example:
public interface IGenericRepository<T> where T : class
{
T Get(object id);
IQueryable<T> GetAll();
void Insert(T entity);
void Delete(T entity);
void Save(T entity);
}
Then you can inject a repository into a controller:
public class MyController
{
private readonly IGenericRepository<Foo> _fooRepository;
public MyController(IGenericRepository<Foo> fooRepository)
{
_fooRepository = fooRepository;
}
}
This keeps UI free of any DB dependencies and makes testing easier; from unit tests you can inject any mock that implements IRepository. This also allows the repository to implement and switch between technologies like Dapper or Entity Framework without any client changes and at any time.
The above example used a generic repository, but you don't have to; you can create a separate interface for each repository, e.g. IFooRepository.
There are many examples and many variations of how repository pattern can be implemented, so google some more to understand it. Here is one of my favorite articles re. layered architectures.
Another note: For small projects, it should be OK to put queries directly into controllers...
I can't speak for dapper personally, but I've always restricted my db access to models only except in very rare circumstances. That seems to make the most sense in my opinion.
A little more info: http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller
A model notifies its associated views and controllers when there has been a change in its state. This notification allows the views to produce updated output, and the controllers to change the available set of commands. A passive implementation of MVC omits these notifications, because the application does not require them or the software platform does not support them.
Basically, data access in models seems to be the standard.
I agree with #void-ray regarding the repository model. However, if you don't want to get into interfaces and dependency injection you could still separate out your data access layer and use static methods to return data from Dapper.
When I am using Dapper I typically have a Repository library that returns very small objects or lists that can then be mapped into a ViewModel and passed to the View (the mapping is done by StructureMap, but could be handled in the controller or another helper).

Is it sometimes okay to use service locator pattern in a domain class?

This question may be more appropriate for the Programmers stack. If so, I will move it. However I think I may get more answers here.
So far, all interface dependencies in my domain are resolved using DI from the executing assembly, which for now, is a .NET MVC3 project (+ Unity IoC container). However I've run across a scenario where I think service locator may be a better choice.
There is an entity in the domain that stores (caches) content from a URL. Specifically, it stores SAML2 EntityDescriptor XML from a metadata URL. I have an interface IConsumeHttp with a single method:
public interface IConsumeHttp
{
string Get(string url);
}
The current implementation uses the static WebRequest class in System.Net:
public class WebRequestHttpConsumer : IConsumeHttp
{
public string Get(string url)
{
string content = null;
var request = WebRequest.Create(url);
var response = request.GetResponse();
var stream = response.GetResponseStream();
if (stream != null)
{
var reader = new StreamReader(stream);
content = reader.ReadToEnd();
reader.Close();
stream.Close();
}
response.Close();
return content;
}
}
The entity which caches the XML content exists as a non-root in a much larger entity aggregate. For the rest of the aggregate, I am implementing a somewhat large Facade pattern, which is the public endpoint for the MVC controllers. I could inject the IConsumeHttp dependency in the facade constructor like so:
public AnAggregateFacade(IDataContext dataContext, IConsumeHttp httpClient)
{
...
The issue I see with this is that only one method in the facade has a dependency on this interface, so it seems silly to inject it for the whole facade. Object creation of the WebRequestHttpConsumer class shouldn't add a lot of overhead, but the domain is unaware of this.
I am instead considering moving all of the caching logic for the entity out into a separate static factory class. Still, the code will depend on IConsumeHttp. So I'm thinking of using a static service locator within the static factory method to resolve IConsumeHttp, but only when the cached XML needs to be initialized or refreshed.
My question: Is this a bad idea? It does seem to me that it should be the domain's responsibility to make sure the XML metadata is appropriately cached. The domain does this periodically as part of other related operations (such as getting metadata for SAML Authn requests & responses, updating the SAML EntityID or Metadata URL, etc). Or am I just worrying about it too much?
It does seem to me that it should be the domain's responsibility to
make sure the XML metadata is appropriately cached
I'm not sure about that, unless your domain is really about metadata manipulation, http requests and so on. For a "normal" application with a non-technical domain, I'd rather deal with caching concerns in the Infrastructure/Technical Services layer.
The issue I see with this is that only one method in the facade has a
dependency on this interface, so it seems silly to inject it for the
whole facade
Obviously, Facades usually don't lend themselves very well to constructor injection since they naturally tend to point to many dependencies. You could consider other types of injection or, as you pointed out, using a locator. But what I'd personnaly do is ask myself if a Facade is really appropriate and consider using finer-grained objects instead of the same large interface in all of my controllers. This would allow for more modularity and ad-hoc injection rather than inflating a massive object upfront.
But that may just be because I'm not a big Facade fan ;)
In your comment to #ian31, you mention "It seems like making the controller ensure the domain has the correct XML is too granular, giving the client too much responsibility". For this reason, I'd prefer the controller asks its service/repository (which can implement the caching layer) for the correct & current XML. To me, this responsibility is a lot to ask of the domain entity.
However, if you're OK with the responsibilities you've outlined, and you mention the object creation isn't much overhead, I think leaving the IConsumeHttp in the entity is fine.
Sticking with this responsibility, another approach could be to move this interface down into a child entity. If this was possible for your case, at least the dependency is confined to the scenario that requires it.

Resources