Reputation:
In CarTrackr project, It use some technique that creates only 1 repository instance for all request in Asp.net Mvc website and uses UnityControllerFactory class to manage all repository instanes(send to requested controller).
Is there any benefit to using single repository instance when compare with creating new repository instance every request?
I know, it may improve overall performance. But, Does it cause any transcation problem?
partial Global.asax
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
RegisterDependencies();
}
protected static void RegisterDependencies() {
IUnityContainer container = new UnityContainer();
// Registrations
container.RegisterType<IUserRepository, UserRepository>(new ContextLifetimeManager<IUserRepository>());
container.RegisterType<ICarRepository, CarRepository>(new ContextLifetimeManager<ICarRepository>());
// Set controller factory
ControllerBuilder.Current.SetControllerFactory(
new UnityControllerFactory(container)
);
}
}
partial CarController.cs
[Authorize]
public class CarController : Controller
{
private IUserRepository UserRepository;
private ICarRepository CarRepository;
public CarController(IUserRepository userRepository, ICarRepository carRepository)
{
UserRepository = userRepository;
CarRepository = carRepository;
}
}
Thanks,
Upvotes: 4
Views: 909
Reputation: 77278
I think you're misunderstanding whats happening with the ContextLifeTimeManager. By passing the manager into the Register() method your telling Unity to set the caching scope for your repository instance to HttpContext.
It is actually incorrect to say:
It use some technique that creates only 1 repository instance for all request in Asp.net > Mvc website
There is not a repository singleton. Unity is creating one for each request. It sounds like this is actually your desired behavior.
When the manager's scope is set to HttpContext the container looks to HttpContext for an existing instance of the requested type (in this case, your repository). Since the HttpContext is fresh on each request, the container will not have this instance, thus a new one will be created.
When you ask:
Is there any benefit to using single repository instance when compare with creating new repository instance every request?
No.
As far as transaction problems: Threading will def be an issue. The CarRepository appears to be using Linq2Sql or Linq2Entities. Its ctor requires an active datacontext. DataContext is NOT thread safe. If the datacontext is being stored at a scope higher than the current request, there will be problems.
Upvotes: 1
Reputation: 1062512
Creating a repository instance per request by itself shouldn't cause any performance issue; the repository is often pretty shallow, and when it needs to access data things like connection pooling minimise the cost of establishing actual connections. Object creation is astonishingly cheap, especially for short-lived things like web requests where the object gets collected while still in "generation zero".
As to whether to have a single repository or a repository per instance - that depends on the repository ;-p
The biggest question is: is your repository thread safe? If not: one per request.
Even if it is though; if your repository itself keeps something like a LINQ-to-SQL DataContext
(that you synchronize somehow), then you have big problems if you keep this long-term, in particular with the identity manager. You'll quickly use a lot of memory and get stale results. Far form ideal.
With a single repository instance, you will probably also end up with a lot of blocking trying to get thread safety. This can reduce throughput. Conversely, the database itself has good ways of achieving granular locks - which is particularly useful when you consider that often, concurrent requests will be looking at separate tables etc - so no blocking at the database layer. This would be very hard to do just at the repository layer - so you'd probably have to synchronize the entire "fetch" - very bad.
IMO, one per request is fine in most cases. If you want to cache data, do it separately - i.e. not directly on the repository instance.
Upvotes: 3
Reputation: 3384
Using the new ContextLifetimeManager());, the lifetime of a repository is limited to one request. This means that evry request each repository is instantiated (if needed) and destroyed once a response has been sent to the client.
Upvotes: 0