DBContext dependency injection within Web Api using repositories [duplicate] - c#

I am trying to use Ninject and OpenAccess for the first time. Please help me with the following. Here is what my project looks like...
public class ContentController : Controller
{
private ContentService contentSvc;
public ContentController(ContentService contentSvc)
{
this.contentSvc = contentSvc;
}
}
The following class is under a folder in my web app.
public class ContentService
{
private IContentRepository contentRepository;
public ContentService(IContentRepository contentRepository)
{
this.contentRepository = contentRepository;
}
public void InsertContent(Content content)
{
contentRepository.InsertContent(content);
}
}
The following repository belongs to a separate assembly.
public class ContentRepository : IContentRepository
{
DBContext db;
public ContentRepository(DBContext _db)
{
db = _db;
}
public void InsertContent(Content content)
{
db.Add(content);
}
}
Here is what Ninject binding look like..
kernel.Bind<ContentService>().To<ContentService>().InRequestScope();
kernel.Bind<IContentRepository>().To<ContentRepository>().InRequestScope().WithConstructorArgument("_db", new DBContext());
Everything works fine if I fetch one page at a time. I am using a simple tool 'XENU' to fetch multiple pages simultaneously. This is when I get errors with DBContext by fetching multiple pages at a time.
I am not sure if Ninject is dosposing the DBContext in each REQUEST?? I get different errors, e.g. 'Object reference not set to an instance of an object.', OR 'ExecuteReader requires an open and available Connection. The connection's current state is open.'
P.S.
I have ContentService under a folder in my MVC web app. ContentRepository is a separate assembly. I will be adding business logic in ContentService and use 'ContentRepository' only for CRUD operations. Also, please let me know if this architecture is okay or is there a better way to create services and repositories.

Here's how I would do your Ninject bindings,
kernel.Bind<DBContext>().ToSelf().InRequestScope();
kernel.Bind<ContentService>().ToSelf().InRequestScope();
kernel.Bind<IContentRepository>().To<ContentRepository>().InRequestScope();
This pattern should work fine in the example above with EF and Ninject.

Related

Share my dbContext with all my repository/service class?

I'm working on a classic .Net Framework Web API solution.
I have 3 layers. Let's call them
MVC - with POST, GET, UPDATE, DELETE controllers.
BIZZ - for business with my service class. My service class are king of repositories with CREATE, READ, UPDATE, DELETE and specific methods.
DATA - with POCO and definition of DB context.
I will not develop the EF layer. It is a classic Entity Framework project with POCO.Here is a sample of a Service and with BaseService class
public abstract class Service : IDisposable
{
protected DbContext dbContext = new DbContext();
public void Dispose()
{
dbContext.Dispose();
}
}
Then I have a cart service and a order service. They are similar in their structure so I will only write the code useful for this example.
public class CartService : Service
{
public Cart Create(Cart cart)
{
// Create the cart
}
public Cart Read(Guid id)
{
// Read
}
public Cart Update(Cart cart)
{
// I do some check first then
}
public void Delete(Cart cart)
{
// Delete
}
public void Checkout(Cart cart)
{
// Validation of cart removed in this example
dbContext.Cart.Attach(cart);
cart.DateCheckout = DateTime.UtcNow;
dbContext.Entry(cart).State = EntityState.Modified; // I think this line can be removed
dbContext.SaveChanges();
using (var orderService = new OrderService())
{
foreach (var order in cart.Orders)
{
order.DateCheckout = cart.DateCheckout;
order.Status = OrderStatus.PD; // pending
orderService.Update(order);
}
}
}
}
public class OrderService : Service
{
public Cart Create(Cart cart)
{
// Create the cart
}
public Cart Read(Guid id)
{
// Read
}
public Cart Update(Cart cart)
{
dbContext.Entry(order).State = EntityState.Modified;
dbContext.SaveChanges();
// More process here...
return order;
}
public void Delete(Cart cart)
{
// Delete
}
}
So, I have a service, cart service, that call another service, order service. I must work like this because I cannot simply accept the cart and all orders in it as it is. When I save a new order or update an existing order I must create a record in some other tables in other databases. The code is not in my example. So, I repeat I have a service that call another service and then I have 2 dbContext. At best this just create 2 context in memory, at worst this create exception. Exception like you cannot attach an entity to 2 contexts or this entity is not in context.
Well, I would like all my service use the same context. I suppose you will al tell me to use Dependency Injection. Yes, well ok but I don't want, each time I create a new service have to pass the context. I don't want to have to do that:
public void Checkout(Cart cart)
{
// ...
using (var orderService = new OrderService(dbContext))
{
// ...
}
}
I would like to do something that impact my base service only if possible. A singleton maybe... At this point I can see your face. Yes I know Singleton are soo bad. Yes but i'm doing a IIS Web API. Each request is a new instance. I don't care about the impact of the singleton. And I can load my database by changing the connection string in config file so the benefit of DI is there already. Well, I also know it is possible to have singleton with DI. I just don't know how.
So, what can I do to be sure I share my dbContext with all my services?
Disclaimer: This example is not intended to be a "good" one and certainly does not follow best practices, but faced with an existing legacy code base which from your example already suffers from a number of questionable practices, this should get you past the multiple context issues.
Essentially if you're not already using a IoC Container to perform dependency injection then what you need is to introduce a unit of work to manage the scope of a DbContext where your base Service class provides a DbContext provided by the unit of work. (Essentially a DbContext Registry)
For the unit of work and assuming EF6 I would recommend Mehdime's DbContextScope which is available as a NuGet package. Alternatively you can find the source code on Github and implement something similar without too much trouble. I like this pattern because it leverages the CallContext to serve as the communication layer between the ContextScope (Unit of Work) created by the DbContextScopeFactory and the AmbientDbContextScope. This will probably take a little time to get your head around but it injects very nicely into legacy applications where you want to leverage the Unit of Work and don't have dependency injection.
What it would look like:
In your Service class you would introduce the AmbientDbContextLocator to resolve your DbContext:
private readonly IAmbientDbContextLocator _contextLocator = new AmbientDbContextLocator();
protected DbContext DbContext
{
get { return _contextLocator.Get<DbContext>(); }
}
And that's it. Later as you refactor to accommodate Dependency injection, just inject the AmbientDbContextLocator instead of 'new'ing it up.
Then, in your web API controllers where you are using your services, (not the services themselves) you need to add the DbContextScopeFactory instance..
private readonly IDbContextScopeFactory _contextScopeFactory = new DbContextScopeFactory();
Lastly, in your API methods, when you want to call your services, you need to simply use the ContextScopeFactory to create a context scope. The AmbientDbContextLocators will retrieve the DbContext from this context scope. The context scope you create with the factory will be done in a using block to ensure your contexts are disposed. So, using your Checkout method as an example, it would look like:
In your Web API [HttpPost] Checkout() method:
using (var contextScope = _contextScopeFactory.Create())
{
using(var service = new CartService())
{
service.Checkout();
}
contextScope.SaveChanges();
}
Your cart service Checkout method would remain relatively unchanged, only instead of accessing dbContext as a variable (new DbContext()) it will access the DbContext property which gets the context through the context locator.
The Services can continue to call DbContext.SaveChanges(), but this isn't necessary and the changes will not be committed to the DB until the contextScope.SaveChanges() is called. Each service will have its own instance of the Context Locator rather than the DbContext and these will be dependent on you defining a ContextScope to function. If you call a Service method that tries to access the DbContext without being within a using (var contextScope = _contextScopeFactory.Create()) block you will receive an error. This way all of your service calls, even nested service calls (CartService calls OrderService) will be interacting with the same DbContext instance.
Even if you just want to read data, you can leverage a slightly faster DbContext using _contextScopeFactory.CreateReadOnly() which will help guard against unexpected/disallowed calls to SaveChanges().
When using the ASP.NET Core stack, the tutorial for using EF with it defaults to using DI to provide your DB context, just not with a service layer. That said, it actually does the right thing for this out of the box. I'll give a brief rundown of the bare minimum necessary for this to work, using whatever the latest versions of ASP.NET Core Web API and EF Core were on NuGet at the time of writing.
First, let's get the boilerplate out of the way, starting with the model:
Models.cs
public class ShopContext : DbContext
{
public ShopContext(DbContextOptions options) : base(options) {}
// We add a GUID here so we're able to tell it's the same object later.
public string Id { get; } = Guid.NewGuid().ToString();
public DbSet<Cart> Carts { get; set; }
public DbSet<Order> Orders { get; set; }
}
public class Cart
{
public string Id { get; set; }
public string Name { get; set; }
}
public class Order
{
public string Id { get; set; }
public string Name { get; set; }
}
Then some bare-bones services:
Services.cs
public class CartService
{
ShopContext _ctx;
public CartService(ShopContext ctx)
{
_ctx = ctx;
Console.WriteLine($"Context in CartService: {ctx.Id}");
}
public async Task<List<Cart>> List() => await _ctx.Carts.ToListAsync();
public async Task<Cart> Create(string name)
{
return (await _ctx.Carts.AddAsync(new Cart {Name = name})).Entity;
}
}
public class OrderService
{
ShopContext _ctx;
public OrderService(ShopContext ctx)
{
_ctx = ctx;
Console.WriteLine($"Context in OrderService: {ctx.Id}");
}
public async Task<List<Order>> List() => await _ctx.Orders.ToListAsync();
public async Task<Order> Create(string name)
{
return (await _ctx.Orders.AddAsync(new Order {Name = name})).Entity;
}
}
The only notable things here are: the context comes in as a constructor parameter as God intended, and we log the ID of the context to verify when it gets created with what.
Then our controller:
ShopController.cs
[ApiController]
[Route("[controller]")]
public class ShopController : ControllerBase
{
ShopContext _ctx;
CartService _cart;
OrderService _order;
public ShopController(ShopContext ctx, CartService cart, OrderService order)
{
Console.WriteLine($"Context in ShopController: {ctx.Id}");
_ctx = ctx;
_cart = cart;
_order = order;
}
[HttpGet]
public async Task<IEnumerable<string>> Get()
{
var carts = await _cart.List();
var orders = await _order.List();
return (from c in carts select c.Name).Concat(from o in orders select o.Name);
}
[HttpPost]
public async Task Post(string name)
{
await _cart.Create(name);
await _order.Create(name);
await _ctx.SaveChangesAsync();
}
}
As above, we take the context as a constructor parameter to triple-check it's what it should be; we also need it to call SaveChanges at the end of an operation. (You can refactor this out of controllers if you want to, but they'll work just fine as units of work for now.)
The part that ties this together is the DI configuration:
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
// Use whichever provider you have here, this is where you grab a connection string from the app configuration.
services.AddDbContext<ShopContext>(options =>
options.UseInMemoryDatabase("Initrode"));
services.AddScoped<CartService>();
services.AddScoped<OrderService>();
}
AddDbContext() defaults to registering a DbContext to be created per-request by the container. Web API provides the AddControllers method that puts those into the DI container, and we also register our services manually.
The rest of Startup.cs I've left as-is.
Starting this up and opening https://localhost:5001/shop should log something like:
Context in CartService: b213966e-35f2-4cc9-83d1-98a5614742a3
Context in OrderService: b213966e-35f2-4cc9-83d1-98a5614742a3
Context in ShopController: b213966e-35f2-4cc9-83d1-98a5614742a3
with the same GUID for all three lines in a request, but a different GUID between requests.
A little additional explanation of what goes on above:
Registering a component in a container (using Add() and such above) means telling the container those components exist and that it should create them for you when asked, as well as what identifiers they're available under and how to create them. The defaults for this are more or less "make the component available as its class, and create it by calling its one public constructor, passing other registered components into it" - the container looks at the constructor signature to figure this out.
"Scoped" in an ASP.NET Core app means "per-request." I think in this case one could also use services with a transient lifetime - a new one created every time it's needed, but they'll still get the same DbContext as long as they're created while handling the same request. Which one to do is a design consideration; the main constraint is that you can't inject shorter-lived components into longer-lived components without having to use more complex techniques, which is why I favour having all components as short-lived as possible. In other words, I only make things longer-lived when they actually hold some state that needs to live for that time, while also doing that as sparingly as possible because state bad. (Just recently I had to refactor an unfortunate design where my services were singletons, but I wanted my repositories to be per-request so as to be able to inject the currently logged in user's information into the repository to be able to automatically add the "created by" and "updated by" fields.)
You'll note that with support for doing things this way being built-in to both ASP.NET Core and EF Core, there's actually very little extra code involved. Also, the only thing needed to go from "injecting a context into your controllers" (as the tutorial does) to "injecting a context into services that you use from your controllers" is adding the services into DI - since the controller and context are already under DI, anything new you add can be injected into them and vice versa.
This should give you a quick introduction into how to make things "just work" and shows you the basic use case of a DI container: you declaratively tell it or it infers "this is an X", "this is an Y", "this is a Z and it needs to be created using an X and a Y"; then when you ask the container to give you a Z, it will automagically first create an X and Y, then create Z with them. They also manage the scope and lifetime of these objects, i.e. only create one of a type for an API request. Beyond that it's a question of experience with them and familiarity with a given container - say Ninject and Autofac are much more powerful than the built-in one - but it's variations on the same idea of declaratively describing how to create an object possibly using other objects (its dependencies) and having the container "figure out" how to wire things together.

Implementing a Simple Repository, Unit of Work with Dependency Injection

I have been trying to create a Repository Pattern along with Dependency injection, But Looks like I am missing some simple step. Here is my code
public class HomeController
{
private readonly ILoggingRepository _loggingRepository;
public HomeController(ILoggingRepository loggingRepository)
{
_loggingRepository = loggingRepository;
}
public void MyMethod()
{
string message = "MyMessage Called";
_loggingRepository .LogMessage(message);
}
}
// ILoggingRepository.cs
public interface ILoggingRepository
{
void LogMessage(string message);
}
// LoggingRepository.cs
public class LoggingRepository : ILoggingRepository
{
public void LogMessage(string message)
{
using (var dbContext = new DbContext())
{
var serviceLog = new Log() { Message = message, Logged = DateTime.UtcNow };
dbContext.Logs.Add(serviceLog);
dbContext.SaveChanges();
}
}
}
This works perfectly all right so far, but the problem arises when i make more than one repository calls.
Now I know that Entity framework 6.0 has inbuilt unit of work representation so I didn't created a UnitofWork Interface or class
But the problem appears when I do something like this in two different transactions. Lets say
Area area = _areaRepository.GetArea(); // Line 1
area.Name = "NewArea"; // Line 2
_areaRepository.SaveArea(area); // Line 3
now because it _areaRepository creates a new DbContext in Line 3, it doesn't changes the name of area as it doesn't consider EntityState.Modified
I have to explicitly set that, which isn't correct.
So I guess I need to do all this in single Transaction, Where I am doing wrong here ?
What is the correct and best way to achieve this, Should I inject my DbContext also into the repository?
This is how I doit all times:
If dont use Repository or Unit of Work layers, because Entity Framework db Context already implements those patterns. So, I only have a Service layer:
public interface IBaseService<VO, ENT>{
IQueryable<VO> GetAll();
VO Get(object id);
}
public abstract class BaseService<VO, ENT> : IBaseService<VO, ENT>{
MyContext db;
public BaseService(MyContext db){
this.db = db;
}
public IQueryable<VO> GetAll(){
return db.Set<ENT>().ProjectTo<VO>();
}
}
A service class have a dbContext injected in the constructor. This classes are located in a Service library. Then, how the dbContext and the service are resolved is a problem of the project who will be using them. The ProjectTo method is an extension for IQueryable from the Automapper Nuget. For example:
A Windows Service needs all services instance in the same thread shares the same dbContext. So, in the windows service project, I use Ninject https://www.nuget.org/packages/Ninject/4.0.0-beta-0134, this library is a dependency resolver, wich I use to configure how dependencies are builded, creating a Kernel, like this:
var kernel = new StandardKernel();
kernel.Bind<MyContext>().ToSelf().InThreadScope();
kernel.Bind<IServiceImplInterface>().To<ServiceImplClass>().InThreadScope();
I you are creating a Web project, you will need to install a aditional nuget (Ninject.WebCommon, Ninject.Web.COmmon.WebHost, Ninject.MVC5) to provide a .InRequestScope() method to the binding configuration, like this:
var kernel = new StandardKernel();
kernel.Bind<MyContext>().ToSelf().InRequestScope();
kernel.Bind<IServiceImplInterface>().To<ServiceImplClass>().InRequestScope();
You need setup those kernel when the app startup. In a web project is in the global.asax, in a windows service project, should be in the Service constructor:
You can visit www.ninject.org/learn.html to learn more about ninject. But, there are othres like Autofac or Caste Windsor, it is up to you. If you like to keep using the repository pattern, just use Ninject inject them into the Service layer, like i did with the dbContext.
The best approach is to have one instance of DbContext, injecting it on each repository implementation. That way you will have a single instance of the database context, so EF will be able to detect changes on the entity objects.
If you need to use isolated dbContexts as in your example, then you need to explicitly set the state of the object as Modified.
Depending on the type of project, you should set the context on a specific scope. For example, for web applications one option is to use instance per Web request (per lifetime scope). Check this url where you can see a good explanation of the different instance scopes.
The using statement simply creates a new scope, executing the Dispose() method after the code block. EF does a lot on the background to maintain the UoW and state of the objects, but in your case, with the using, you are not using this fature.
First, a DbContext is a repository. If you want to wrap it in a custom repository, they should have the same lifecycle.
Second, your Unit-of-work is your controller. The repository should be scoped to unit-of-work.
This means that your repository needs to be Disposable, since the DbContext is.
So something like:
public interface ILoggingRepository : IDisposable
{
void LogMessage(string message);
}
// LoggingRepository.cs
public class LoggingRepository : ILoggingRepository
{
MyDbContext db;
public LoggingRepository(MyDbContext db)
{
this.db = db;
}
public void Dispose()
{
db.Dispose();
}
public void LogMessage(string message)
{
var serviceLog = new MonitoringServiceLog() { Message = message, Logged = DateTime.UtcNow };
db.MonitoringServiceLogs.Add(serviceLog);
db.SaveChanges();
}
}
If your ILoggingRepository wan't a database, it might be a file or something else that is expensive to create or open and needs to be closed.

Entity Framework Constructor Injection in Asp.net Core

I'm using Entity Framework in ASP.net Core, I have many classes where I am using an instance of the DbContext to interact with the database, I'm using constructor injection in every class and controller but I feel like a trained monkey repeating that code all the time, maybe I'm doing this the wrong way and there are better ways to do this. I'm feeling tired to write again and again the same code for every controller and every class I'm using an instance of DbContext..
Startup class:
public void ConfigureServices(IServiceCollection services)
{
services.Configure<DBConnection> Configuration.GetSection("ConnectionStrings"));
}
That code is fine, no problem at all, but now: Do I need to repeat the code below for every class and controller?? I know I have not read a lot yet about services and that I might be losing something obvious, I'm just copying the constructors, but in some classes where I need instances I need to add a field named _connectionAccessor of type IOptions<DBConnection>:
public FirstController(IOptions<DBConnection> connectionsAccessor)
{
_context = new DataContext(connectionsAccessor);
_connectionAccessor = connectionsAccessor;
}
public EmailController(IOptions<DBConnection> connectionsAccessor)
{
this.ctx = new DataContext(connectionsAccessor);
_connectionAccessor = connectionsAccessor;
}
public MyRepository(IOptions<DBConnection> connectionsAccessor)
{
_context = new DataContext(connectionsAccessor);
_connectionAccessor = connectionsAccessor;
}
And like that for every controller and class, and I have a lot of classes and controllers, is this the only way?
Oh this is my DbContext class:
public class DataContext : DbContext
{
public DataContext(IOptions<DBConnection> connectionsAccessor)
{
this.Database.Connection.ConnectionString = connectionsAccessor.Value.MySQLContext;
}

Ninject not injecting service into Web Forms page

I've trying to use Ninject for DI in a combined ASP.NET Web Forms and MVC project. I installed the following packages (and their dependencies) via NuGet:
Ninject.MVC5 3.2.1.0
Ninject.Web 3.2.1.0
In ~/App_Start/NinjectWebCommon.cs I register services:
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<ITermusRepository>().To<TermusOracleRepository>();
}
In MVC controllers, I use constructor injection to retrieve my ITermusRepository implementation:
public class Appraisal2013_2014FullController : Controller
{
ITermusRepository repo { get; set; }
public Appraisal2013_2014FullController(ITermusRepository Repo)
{
repo = Repo;
}
}
MVC works great, I use the repo later in my action methods to successfully retrieve data. All is well there.
In Web Forms, I use attribute injection.
public partial class _2013_2014_TERMUS_PaperTermus : BasePage
{
[Inject]
ITermusRepository repo { get; set; }
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
var appraisal = repo.LoadByTermusId<Termus2013_2014EndYear>(Request.QueryString["TERMUSID"]);
}
}
However, repo.LoadByTermusId() call fails with a NullReferenceException because repo is null.
System.NullReferenceException: Object reference not set to an instance
of an object.
Clearly Ninject is set up correctly at least for MVC. I don't understand why my implementation of ITermusRepository isn't getting injected into my Web Forms code behind. What can I do to get it to inject it properly?
I used Jason's answer from How can I implement Ninject or DI on asp.net Web Forms? as my pattern for getting this working. I don't want to use Joe's answer, as it requires modifying the base class of the global application class, pages, master pages, ASMX services, generic handlers etc. And that appears unnecessary in the current version of Ninject.
[Inject]
ITermusRepository repo { get; set; }
needed to be
[Inject]
public ITermusRepository repo { get; set; }
That fixed the problems with my .aspx Web Forms pages. But it wasn't injecting them into my .ashx generic handlers. Since I don't have many of those, I created a constructor in my handler class and retrieved the service from the kernel.
ITermusRepository repo { get; set;}
public GetPDF()
{
var kernel = TERMUS.App_Start.NinjectWebCommon.CreateKernel();
repo = kernel.Get<ITermusRepository>();
}

Using Fluent NHibernate with a Data Access Layer

First a little background: I have a solution with the following 3 projects in it:
MVC Project (User facing website)
API Project (business logic project)
Data Access Project (project where NHibernate lives)
I have the Fluent mappings in the DA layer, and (for now) I build the Hibernate SessionFactory in the GLobal.asax of the MVC site. This is not ideal as I want to have NHibernate completely contained in the DA layer and have the MVC app only communicate with the API layer. Also, I want to build the SessionFactory only once as it is an expensive operation.
To make things more complicated I have an inheritance structure like so:
User object in API layer inherits from
User data object in DA layer inherits from
Data object in DA layer.
Data object is responsible for saving the object to the database as the saving function is the same across all objects and I do not want to repeat code. The problem I am having is how do I save the User object to the database from inside the Data object class while using a SessionFactory that I instantiated when the user logged into the website and can persist through out their session.
If anything is not explained clearly please let me know.
One way to do that would be using the DI pattern, with e.g. Unity.
Implement your data object having a constructor which takes for example an IRepository interface. The implementation of this interface handles the nHibernate session factory...
Your data object could also be generic where T is one for example User data object. Then you implement a methods in data object to e.g. save, update, delete T with the injected IRepository
pseudo code for a data object
public interface IEntity
{
}
public interface IRepository
{
ISession Session { get; }
}
public class DataObjectBase<T> where T : IEntity
{
private IRepository Repository { get; set; }
public DataObjectBase(IRepository repository)
{
this.Repository = repository;
}
public T Get(int id)
{
return Repository.Session.Get<T>(id);
}
public void Save(T value)
{
Repository.Session.Save(value);
}
public void Update(T value)
{
Repository.Session.Update(value);
}
public void Delete(T value)
{
Repository.Session.Delete(value);
}
public IQueryable<T> Query()
{
return Repository.Session.Query<T>();
}
}
Implementation of your specific data object
public class ADataObject : IEntity
{
public int Id { get; set; }
// [...]
}
Implementation of your data context for the data object
public class ADataObjectContext : DataObjectBase<ADataObject>
{
public ADataObjectContext(IRepository repository)
: base(repository)
{
}
}
A simple example test using Unity
public class Test
{
public void Run()
{
IUnityContainer myContainer = new UnityContainer();
myContainer.RegisterType<IRepository, NHibernateRepository>();
var ctx = myContainer.Resolve<ADataObjectContext>();
var obj = ctx.Query().Where(p => p.Id == 2);
}
}
Of cause you would have to implement the NHibernateRespository to do whatever you want it to.
The UnityContainer initialization should be done within your global.asax within the MVC project. You can also configure Unity via web.config.
The NHibernateRespository should actually be a singleton. This can either be implemented by you, or you simply use the Unity functionality to instantiate your type as singleton. The new ContainerControlledLifetimeManager() does exactly that.
Instead of exposing the session as a property you can of cause expose a method which opens a new session. Or you implement a Begin and End unit of work, which is common practice in web environments...
Other links for a normal repository pattern, and unit of work, unity... or simply search on Google for nhibernate repository pattern
http://slynetblog.blogspot.de/2011/11/in-spite-of-common-now-approach-of.html
http://blog.bobcravens.com/2010/07/using-nhibernate-in-asp-net-mvc/
http://msdn.microsoft.com/en-us/library/dd203101.aspx
You can use this options:
Using AOP: when a function is called in API layer, AOP creates a session and passes the value parameters in methods or constructors to DA layer.
From MVC project to DA layer, it passes a session to DA layer with parameters in method o constructors, through all the layers.
Thinks the session is always associated with the interface layer.

Categories