Will my session be automatically closed? - asp.net-mvc

Edit
Orignal Title: My transaction is closed by the time it gets to my Repo. What am I doing wrong?
I got a answer to my origanl questions(I forgot to open the transaction lol). Now I am wondering if my code is automatically closing the session or if I have to somehow tell it to do this.
Hi
I am using mvc 3.0, nhibernate, fluent nhibernate and ninject 2.0
Global.asax
// Note: For instructions on enabling IIS6 or IIS7 classic mode,
// visit http://go.microsoft.com/?LinkId=9394801
public class MvcApplication : System.Web.HttpApplication
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
}
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
}
protected void Application_Start()
{
// Hook our DI stuff when application starts
SetupDependencyInjection();
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}
public void SetupDependencyInjection()
{
// Tell ASP.NET MVC 3 to use our Ninject DI Container
DependencyResolver.SetResolver(new NinjectDependencyResolver(CreateKernel()));
}
protected IKernel CreateKernel()
{
var modules = new INinjectModule[]
{
new NhibernateModule(),
new ServiceModule(),
new RepoModule()
};
return new StandardKernel(modules);
}
}
Session Factory
public class NhibernateSessionFactory
{
public ISessionFactory GetSessionFactory()
{
ISessionFactory fluentConfiguration = Fluently.Configure()
.Database(MsSqlConfiguration.MsSql2008.ConnectionString(c => c.FromConnectionStringWithKey("test")))
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<MyMaps>())
.BuildSessionFactory();
return fluentConfiguration;
}
}
Session Factory Provider
public class NhibernateSessionFactoryProvider : Provider<ISessionFactory>
{
protected override ISessionFactory CreateInstance(IContext context)
{
var sessionFactory = new NhibernateSessionFactory();
return sessionFactory.GetSessionFactory();
}
}
Nhibernate Module
public class NhibernateModule : NinjectModule
{
public override void Load()
{
Bind<ISessionFactory>().ToProvider<NhibernateSessionFactoryProvider>().InSingletonScope();
Bind<ISession>().ToMethod(context => context.Kernel.Get<ISessionFactory>().OpenSession()).InRequestScope();
}
}
Service Module
public class ServiceModule : NinjectModule
{
public override void Load()
{
Bind<ITest>().To<Test>();
}
}
Repo Module
public class RepoModule : NinjectModule
{
public override void Load()
{
Bind<IStudentRepo>().To<StudentRepo>();
}
}
HomeController
private readonly ITest test;
public HomeController(ITest test)
{
this.test = test;
}
//
// GET: /Home/
public ActionResult Index()
{
return View();
}
Test(my service layer file)
public class Test : ITest
{
private readonly IStudentRepo studentRepo;
public Test(IStudentRepo studentRepo)
{
this.studentRepo = studentRepo;
}
}
Repo
public class StudentRepo : IStudentRepo
{
private readonly ISession session;
public StudentRepo(ISession session)
{
this.session = session;
}
}
When I look through my debugger at the session that is coming into my repo. It says the session is open and connected but the (session.Transaction).IsActive = false

You're currently set up to use implicit transactions, which I don't believe are exposed through session.Transaction. Of course, Use of implicit transactions is discouraged.

Related

How to register Umbraco RenderMvcControllers in global asax

I am trying to use RenderMvcController and SurfaceController with dependency injection but it doesn't work.
public class SupplierRenderMvcController : RenderMvcController
{
public HomeRenderMvcController(IMembershipService membershipService)
{
_membershipService = membershipService;
}
}
public class SupplierController : SurfaceController
{
public SupplierController(IMembershipService membershipService)
{
_membershipService = membershipService;
}
}
I get an error:
No parameterless constructor defined for this object.
Umbraco's controllers are registered in in Global.asax:
builder.RegisterControllers(typeof(UmbracoApplication).Assembly);
builder.RegisterApiControllers(typeof(UmbracoApplication).Assembly);
I have api controllers using IoC with no problem in other projects of the same solution.
The above controllers are in the main project of the solution though.
This is my full Global.asax of the main project:
public class MvcApplication : IApplicationEventHandler
{
public void OnApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
{
AreaRegistration.RegisterAllAreas();
BundleConfig.RegisterBundles(BundleTable.Bundles);
GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear();
RegisterIoCContainer();
}
public void OnApplicationInitialized(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
{
}
public void OnApplicationStarting(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
{
}
private void RegisterIoCContainer()
{
var builder = new ContainerBuilder();
builder.RegisterControllers(Assembly.GetExecutingAssembly());
builder.RegisterAssemblyModules(Assembly.GetExecutingAssembly());
builder.RegisterModelBinders(Assembly.GetExecutingAssembly());
builder.RegisterModelBinderProvider();
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
builder.RegisterControllers(typeof(UmbracoApplication).Assembly);
builder.RegisterApiControllers(typeof(UmbracoApplication).Assembly);
builder.RegisterApiControllers(Assembly.GetExecutingAssembly‌​());
builder.RegisterModule<WebApiConfig>();
var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
GlobalConfiguration.Configuration.DependencyResolver = new AutofacWebApiDependencyResolver(container);
GlobalConfiguration.Configuration.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
}
}
MembershipService is registered within WebApiConfig:
public class WebApiConfig : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.AddMediatR(this.GetType().Assembly);
builder.RegisterType<MembershipService1>().As<IMembershipService>();
}
}

Using Unity with Web Api 2 gives error does not have a default constructor

I have ASP.NET MVC5 web application and i also have Web API in the same application. I am uisng Unity (version 4) for DI.
I am configuring the Unity container on APP start as below
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
UnityConfiguration.Config();
}
}
public class UnityConfiguration()
{
public void Config()
{
UnityContainer container = new UnityContainer();
container.RegisterType<IMyService, Myservice>();
container.RegisterType<IGenericRepository, GenericRepository>();
container.RegisterType<DbContext, MyEntities>();
}
}
public class GenericRepository:IGenericRepository
{
private DbContext _dbcontext;
public GenericRepository(DbContext dbcontext)
{
_dbcontext = dbcontext;
}
}
public class MyService:IMyService
{
private IGenericRepository _repo;
publi void MyService(IGenericRepository repository)
{
_repo = repository;
}
}
public class MyApiController:ApiController
{
provate IMyService _service;
MyApiController(IMyService myservice)
{
_service = myservice;
}
public IEnumerable<MyModel> GetData()
{
var result = _service.GetData();
return result.ConvertToMyModel();
}
}
However when i call the url like
localhost://lookup/getdata
I get error
Type 'LookupController' does not have a default constructor
How do i solve this issue? Do i need to register each controller i create with Unity or Unity automatically registers all MVC controllers?
I tend to use the Unity.Mvc-package.
You do not need to register the controllers, but you need to register Unity with WebAPI.
public class UnityConfiguration()
{
public IUnityContainer Config()
{
IUnityContainer container = new UnityContainer();
container.RegisterType<IMyService, Myservice>();
container.RegisterType<IGenericRepository, GenericRepository>();
container.RegisterType<DbContext, MyEntities>();
// return the container so it can be used for the dependencyresolver.
return container;
}
}
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Your routes...
// Register Unity with Web API.
var container = UnityConfiguration.Config();
config.DependencyResolver = new UnityResolver(container);
// Maybe some formatters?
}
}
You also need a DependencyResolver:
public class UnityResolver : IDependencyResolver
{
protected IUnityContainer container;
public UnityResolver(IUnityContainer container)
{
if (container == null)
{
throw new ArgumentNullException("container");
}
this.container = container;
}
public object GetService(Type serviceType)
{
try
{
return container.Resolve(serviceType);
}
catch (ResolutionFailedException)
{
return null;
}
}
public IEnumerable<object> GetServices(Type serviceType)
{
try
{
return container.ResolveAll(serviceType);
}
catch (ResolutionFailedException)
{
return new List<object>();
}
}
public IDependencyScope BeginScope()
{
var child = container.CreateChildContainer();
return new UnityResolver(child);
}
public void Dispose()
{
container.Dispose();
}
}
You can also take a look at this similiar question, except for the Owin-part. Unity.WebApi | Make sure that the controller has a parameterless public constructor
I had the same error and in my case the problem was, that i forgot to register a dependency that one of the classes, I had registered for dependency injection, injects in the constructor.
In your example, could it be that you inject something into MyEntities that you forgot to Register?
Install Nuget Package Unit.WebAP instead of Unity.MVC5
Make sure the correct unity package is installed using nuget
I Installed Unity.MVC5 and was facing similar exception "parameterless constructor"
public static void RegisterComponents()
{
var container = new UnityContainer();
// register all your components with the container here
// it is NOT necessary to register your controllers
// e.g. container.RegisterType<ITestService, TestService>();
container.RegisterType<ICar, Tesla>();
GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(container);
}

MVC Repository patterns Bind Data

I am having hard time using Repository patterns, is it possible to create two repository patterns?? One for products, another for orders??
I failed to connect these repositories to databases. I know how to work with one repository, but two with IRepository where T: Entity I am getting lost. The question is whether I can create and will not volatile the rules if create ProductRepository and OrderRepository?
Repository pattern is widely used in DDD (Domain-Driven-Design) you could check it here: http://www.infoq.com/minibooks/domain-driven-design-quickly. Also check this book: http://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215
With regards to your question:
Yes you can use more than 1 repository. Look in this example I use nHibernate session:
// crud operations
public abstract class Repository<T> : IRepository<T> where T : class
{
protected readonly ISession _session;
public Repository(ISession session)
{
_session = session;
}
public T Add(T entity)
{
_session.BeginTransaction();
//_session.SaveOrUpdate(entity);
_session.Save(entity);
_session.Transaction.Commit();
return entity;
}
//...
}
public interface IRepository<T>
{
T Add(T entity);
T Update(T entity);
T SaveOrUpdate(T entity);
bool Delete(T entity);
}
Then my repository looks like this:
public class ProjectRepository : Repository<Project>, IProjectRepository
{
// Project specific operations
}
public interface IProjectRepository : IRepository<Project>
{
Project Add(Project entity);
Project Update(Project entity);
Project find_by_id(int id);
Project find_by_id_and_user(int id, int user_id);
//..
}
Then using Ninject:
Global.asax.cs
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory());
}
Then in NinjectControllerFactory I load the modules:
public class NinjectControllerFactory : DefaultControllerFactory
{
private IKernel kernel = new StandardKernel(new NhibernateModule(), new RepositoryModule(), new DomainServiceModule());
protected override IController GetControllerInstance(RequestContext context, Type controllerType)
{
//var bindings = kernel.GetBindings(typeof(IUserService));
if (controllerType == null)
return null;
return (IController)kernel.Get(controllerType);
}
}
NhibernateModule:
public class NhibernateModule : NinjectModule
{
public override void Load()
{
string connectionString =
ConfigurationManager.ConnectionStrings["sqlite_con"].ConnectionString;
var helper = new NHibernateHelper(connectionString);
Bind<ISessionFactory>().ToConstant(helper.SessionFactory).InSingletonScope();
Bind<ISession>().ToMethod(context => context.Kernel.Get<ISessionFactory>().OpenSession()).InRequestScope();
}
}
Then in RepositoryModule I use Ninject Conventions to automatically bind all repositories with their interfaces:
using Ninject.Extensions.Conventions;
public class RepositoryModule : NinjectModule
{
public override void Load()
{
IKernel ninjectKernel = this.Kernel;
ninjectKernel.Scan(kernel =>
{
kernel.FromAssemblyContaining<ProjectRepository>();
kernel.BindWithDefaultConventions();
kernel.AutoLoadModules();
kernel.InRequestScope();
});
}
}
And in the end I basically inject Repository in the controller:
public class projectscontroller : basecontroller
{
private readonly IProjectRepository _projectRepository;
public projectscontroller(IProjectRepository projectRepository)
{
_projectRepository = projectRepository;
}
[AcceptVerbs(HttpVerbs.Get)]
[Authorize]
public ActionResult my()
{
int user_id = (User as CustomPrincipal).user_id;
var projectList = _projectRepository.find_by_user_order_by_date(user_id);
var projetsModel = new ProjectListViewModel(projectList);
return View("my", projetsModel);
}
}
This way you just create new Repository and its Interface and it will be automatically injected to your controller.

ASP MVC 2 Ninject

I'm trying to learn a bit about MVC and have come across a problem when using Ninject. I want to bind repositories but keep getting the 'Object reference not set to an instance of an object' error.
I have created my NinjectControllerFactory:
public class NinjectControllerFactory : DefaultControllerFactory
{
// A Ninject "kernel" is the thing that can supply object instances
private IKernel kernel = new StandardKernel(new SportsShopServices());
// ASP .NET MVC calls this to get the controller for each request
protected override IController GetControllerInstance(RequestContext context, Type controllerType)
{
if (controllerType == null)
return null;
return (IController) kernel.Get(controllerType);
}
// Configure how abstract sevice types are mapped to concrete implementations
private class SportsShopServices : NinjectModule
{
public override void Load()
{
Bind<IProductRepository>().To<SqlProductsRepository>()
.WithConstructorArgument("connectionString",
ConfigurationManager.ConnectionStrings["AppDb"].ConnectionString);
}
}
}
and my controller :
public class ProductsController : Controller
{
private IProductRepository productsRepository;
// Constructor used with Ninject
public ProductsController(IProductRepository _productsRepository)
{
this.productsRepository = _productsRepository;
}
public ViewResult List()
{
return View(productsRepository.Products.ToList());
}
}
I have modified the Web.config file to provide the db connection string and the Global.asax file Application_Start() method to include:
ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory());
I am working on an example from the PRO ASP .NET MVC 2 book but just can't get this work, been trying all day.
If you just want out-out-the-box ninject functionality, you are doing too much by creating your own controller factory.
all you need is the following in global.asax
public class MvcApplication : NinjectHttpApplication
{
protected override IKernel CreateKernel()
{
var modules = new INinjectModule[]
{
new ServiceModule()
};
return new StandardKernel(modules);
}
protected override void OnApplicationStarted()
{
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
RegisterAllControllersIn(Assembly.GetExecutingAssembly());
}
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
}
internal class ServiceModule : NinjectModule
{
public override void Load()
{
// controllers
this.Bind<Controllers.AccountController>().ToSelf();
this.Bind<Controllers.HomeController>().ToSelf();
// Repository
Bind<Controllers.IFormsAuthentication>().To<Controllers.FormsAuthenticationService>();
Bind<Controllers.IMembershipService>().To<Controllers.AccountMembershipService>();
}
}
}

Is Ninject MVC supposed to work with MVC 2 Preview?

I am running a MVC 2 Preview and this is my first time trying to use Ninject2 MVC
There error that I am continently getting is:
An error occurred when trying to create a controller of type 'MyMVC.Controllers.EventsController'. Make sure that the controller has a parameterless public constructor.
What I have in my Global.cs is this:
public class MvcApplication : NinjectHttpApplication
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.IgnoreRoute("elmah.axd");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
routes.MapRoute(
"Root",
"",
new { controller = "Home", action = "Index", id = "" }
);
}
protected override void OnApplicationStarted()
{
RegisterRoutes(RouteTable.Routes);
RegisterAllControllersIn(Assembly.GetExecutingAssembly());
}
protected override IKernel CreateKernel()
{
return new StandardKernel(new ServiceModule());
}
}
internal class ServiceModule : NinjectModule
{
public override void Load()
{
Bind<IEventService>().To<EventService>();
Bind<IEventRepository>().To<EventRepository>();
}
}
And this is what my Controller looks like.
public class EventsController : Controller
{
private IEventService _eventService;
//
// GET: /Events/
public EventsController(IEventService eventService)
{
_eventService = eventService;
}
public ActionResult Index(string name)
{
return View(_eventService.GetEvent(name));
}
public ActionResult UpcomingEvents()
{
return View(_eventService.GetUpcomingEvents().Take(3).ToList());
}
}
I've not used Ninject, but I would assume you need to implement your own IControllerFactory. Until they update it to MVC 2. Then utilize that instead of RegisterAllControllersIn(..):
ControllerBuilder.Current.SetControllerFactory(new MyNinjectControllerFactory());
EDIT: Again, i'm not all that familiar with Ninject but this might work as a simple factory:
public class MyNinjectControllerFactory : DefaultControllerFactory
{
protected override IController GetControllerInstance(Type controllerType)
{
return [Container].GetInstance(controllerType) as Controller;
}
}
At the risk of stating the obvious, you should try adding a parameterless constructor to your Events Controller.
public class EventsController : Controller
{
private IEventService _eventService;
//
// Parameterless constructor, so NInject will work
public EventsController() {}
//
// Regular constructor
public EventsController(IEventService eventService)
{
_eventService = eventService;
}

Resources