Requestlifetime issue

Mar 7, 2012 at 12:54 PM

I've been testing out Munq and really like it so far, however it seems like the request lifetime isn't working properly in the latest version.  This is a key feature for me and it's quite limiting without it.  Is this something that you expect you'll be able to investigate and/or fix in the near future?

http://munq.codeplex.com/workitem/6797

Coordinator
Mar 7, 2012 at 5:01 PM

I'll look at it tonight

Coordinator
Mar 8, 2012 at 12:29 AM

I have a quick work around for you.  Just regiser something with request lifetime in application_start in the global.ascx

		protected void Application_Start()
		{
			AreaRegistration.RegisterAllAreas();
 
			RegisterGlobalFilters(GlobalFilters.Filters);
			RegisterRoutes(RouteTable.Routes);
 
			var ioc = MunqDependencyResolver.Container;
			ioc.Register<MyThing, MyThing>().AsRequestSingleton(); 
		}

This will cause the event handler to be installed correctly.

 

Matthew

Coordinator
Mar 8, 2012 at 12:56 AM

Also, don't do any registration in the MunqMvc3Startup as this happens to early in the application, hence the error.

Do your Registration from Application_Start and you should be good.

Matthew


Mar 8, 2012 at 11:42 AM

The problem occurs when I attempt to register something with a request lifetime in application_start in global.ascx! :) 

If I change the lifetime to SessionLifetime or AlwaysNewLifetime it works fine.  I am not calling anything apart from SetResolver in MunqMvc3Startup

public static class MunqMvc3Startup
{
    public static void PreStart()
    {
        DependencyResolver.SetResolver(new MunqDependencyResolver());
    }
}

Here is the exception detail in my specific case:

System.InvalidOperationException was caught
  Message=Event handlers can only be bound to HttpApplication events during IHttpModule initialization.
  Source=System.Web
  StackTrace:
       at System.Web.HttpApplication.ThrowIfEventBindingDisallowed()
       at System.Web.HttpApplication.AddSyncEventHookup(Object key, Delegate handler, RequestNotification notification, Boolean isPostNotification)
       at Munq.LifetimeManagers.RequestLifetime.GetInstance(IRegistration registration)
       at Munq.IocContainer.Resolve(String name, Type type)
       at Munq.IocContainer.Resolve[TType]()
       at MyProject.Classes.Common.Utils.IocConfiguration.<>c__DisplayClass27.<RegisterRepositories>b__12(IDependencyResolver ioc) in C:\MyProject\Classes\Common\Utils\IocConfiguration.cs:line 129
       at Munq.IocContainer.<>c__DisplayClassc`1.<Register>b__b(IDependencyResolver c)
       at Munq.Registration.CreateInstance()
       at Munq.IocContainer.Resolve(String name, Type type)
       at Munq.IocContainer.Resolve[TType]()
       at MyProject.Classes.Common.Utils.IocConfiguration.<RegisterControllers>b__37(IDependencyResolver ioc) in C:\MyProject\Classes\Common\Utils\IocConfiguration.cs:line 192
       at Munq.IocContainer.<>c__DisplayClassc`1.<Register>b__b(IDependencyResolver c)
       at Munq.Registration.CreateInstance()
       at Munq.IocContainer.Resolve(String name, Type type)
       at Munq.IocContainer.Resolve[TType]()
       at MyProject.Classes.Common.Utils.IocConfiguration.<RegisterControllers>b__39(IDependencyResolver ioc) in C:\MyProject\Classes\Common\Utils\IocConfiguration.cs:line 211
       at Munq.IocContainer.<>c__DisplayClassf`1.<Register>b__e(IDependencyResolver c)
       at Munq.Registration.GetInstance()
       at Munq.IocContainer.Resolve(String name, Type type)
       at Munq.IocContainer.Resolve[TType](String name)
       at MyProject.Classes.Common.Factories.ControllerFactory.System.Web.Mvc.IControllerFactory.CreateController(RequestContext requestContext, String controllerName) in C:\MyProject\Classes\Common\Factories\ControllerFactory.cs:line 24
  InnerException: 

Coordinator
Mar 8, 2012 at 12:32 PM

I see the problem.  I need to setup the event handler sooner.

A quick fix is to resolve something RequestLifetime registerd in Application_Start

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();

    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);

    var ioc = MunqDependencyResolver.Container;
    ioc.Register<MyThing, MyThing>().AsRequestSingleton();
 
    var aThing = ioc.Resolve<MyThing>();
}

Mar 8, 2012 at 1:03 PM

Unfortunately that doesn't seem to do the trick, it does however change the exception

[NullReferenceException: Object reference not set to an instance of an object.]
   System.Web.PipelineModuleStepContainer.GetEventCount(RequestNotification notification, Boolean isPostEvent) +30
   System.Web.PipelineStepManager.ResumeSteps(Exception error) +1507
   System.Web.HttpApplication.BeginProcessRequestNotification(HttpContext context, AsyncCallback cb) +132
   System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest wr, HttpContext context) +693
Coordinator
Mar 9, 2012 at 1:12 PM

It may be that you are throwing an exception in the constructor of a controller or one of its dependencies. 

Here is what I did to try to recreate your issue:

I created a simple project with a Person class, a PeopleController, and a DbContext, and a test class MyThing.

The Controller's constructor is

		public PeopleController(MyContext db, MyThing aThing)

both dependencies are initialized to RequestLifetime in global.ascx

		protected void Application_Start()
		{
			AreaRegistration.RegisterAllAreas();
 
			RegisterGlobalFilters(GlobalFilters.Filters);
			RegisterRoutes(RouteTable.Routes);
			InitializeIoc();
		}
 
		private void InitializeIoc()
		{
			IocContainer ioc = MunqDependencyResolver.Container;
 
			ioc.Register<MyContextMyContext>().AsRequestSingleton();
			ioc.Register<MyThingMyThing>().AsRequestSingleton();
		}

and everything works.

However, if i create an exception in the constructor of the PeopleController

		public PeopleController(MyContext db, MyThing aThing)
		{
			this.db = db;
			_aThing = aThing;
			string x = null;
			bool test = x.Contains("Junk");
			if (test)
				test = false;
			else
				test = true;
		}

 I get an error very similar to yours

[InvalidOperationException: An error occurred when trying to create a controller of type 'munqError.Controllers.PeopleController'. Make sure that the controller has a parameterless public constructor.]
   System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) +181
   System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(RequestContext requestContext, Type controllerType) +79
   System.Web.Mvc.DefaultControllerFactory.CreateController(RequestContext requestContext, String controllerName) +74
   System.Web.Mvc.MvcHandler.ProcessRequestInit(HttpContextBase httpContext, IController& controller, IControllerFactory& factory) +196
   System.Web.Mvc.<>c__DisplayClass6.<BeginProcessRequest>b__2() +49
   System.Web.Mvc.<>c__DisplayClassb`1.<ProcessInApplicationTrust>b__a() +13
   System.Web.Mvc.SecurityUtil.<GetCallInAppTrustThunk>b__0(Action f) +7
   System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Action action) +22
   System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Func`1 func) +88
   System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +98
   System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state) +50
   System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) +16
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +9479007
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +178

Maybe you have an bug?

Also, I need to add some better error handling for this case :)

Matthew


Mar 9, 2012 at 2:46 PM

As far as I know I don't have any bugs in my code (relating to this issue anyway!).  It works perfectly with everything using an AlwaysNew lifetime.  Even if I simply change my "MyThing" type object from AsAlwaysNew() to AsRequestSingleton() it goes from working to not working.  As noted in my last comment though the inclusion of this quick fix object does change the exception I get from

Event handlers can only be bound to HttpApplication events during IHttpModule initialization.

to this one

[NullReferenceException: Object reference not set to an instance of an object.]
   System.Web.PipelineModuleStepContainer.GetEventCount(RequestNotification notification, Boolean isPostEvent) +30
   System.Web.PipelineStepManager.ResumeSteps(Exception error) +1507
   System.Web.HttpApplication.BeginProcessRequestNotification(HttpContext context, AsyncCallback cb) +132
   System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest wr, HttpContext context) +693

Coordinator
Mar 9, 2012 at 2:56 PM

Is it possible that one of the classes that uses "MyThing" is calling Dispose on it.  This would cause an error when using RequestLifetime, but not if AlwaysNew.

For example, if setting your DbContext to RequestLifetime, and the Controller Disposes of the DbContext, as it does in the scaffolded controllers, then a RenderAction in a View will

  • Spin up a Controller, passing in the DbContext
  • If it has RequestLifetime, then it is not valid
  • BOOM!
Mar 9, 2012 at 3:14 PM

So investigating further, your fix does actually allow the controller to be located and executed etc.  For some reason the error above is thrown after the controller is disposed at the end of the request.

Mar 9, 2012 at 3:25 PM

I just defined a new class

    public class Hack { }

then I call

    container.Register<Hack>(ioc => new Hack()).AsRequestSingleton();

    var hack = container.Resolve<Hack>();

So hack is not actually used anywhere and everything else is using AlwaysNew lifetime

Coordinator
Mar 9, 2012 at 3:27 PM

could you show me your code for registration.

You should not register the controller, as the IocContainer will create concrete classes without registration.

Furthermore, you should not specify a lifetime on them if you do, as the MVC runtime does the lifetime management.

 

Matthew 

Mar 9, 2012 at 3:47 PM
Edited Mar 9, 2012 at 4:18 PM

Here is a representation of it:

// Global.asax.cs
protected void Application_Start()
{

    // Register routes etc...

    // Configure IoC
    IocConfiguration.Configure();
}

// IocConfiguration.cs
public static class IocConfiguration
{
    public class Hack { }

    public static void Configure()
    {
        var container = MunqDependencyResolver.Container;
        container.Register<Hack>(ioc => new Hack()).AsRequestSingleton();
        var hack = container.Resolve<Hack>();

        RegisterRepositories(container);
        RegisterControllers(container);
    }

    private static void RegisterRepositories(IocContainer container)
    {
        container.Register<ISomeRepository>(ioc => new SomeRepository()).WithLifetimeManager(new AlwaysNewLifetime());
        container.Register<ISomeOtherRepository>(ioc => new SomeOtherRepository()).WithLifetimeManager(new AlwaysNewLifetime());
    }

    private static void RegisterControllers(IocContainer container)
    {
        container.Register<IController>("SomeController", ioc => new SomeController(ioc.Resolve<ISomeRepository>()));
        container.Register<IController>("SomeOtherController", ioc => new SomeOtherController(ioc.Resolve<ISomeRepository>(), ioc.Resolve<ISomeOtherRepository>()));
    }

}
Coordinator
Mar 9, 2012 at 4:58 PM

I don't see anything wrong with your registration, but it could be a lot simpler.

The is no need to register the controllers.  For classes, not interfaces, Munq will use the constructor with the most parameters and resolve all the parameter.

While you can specify the function to create the Repositories, Munq will use the contructor with the most parameters if you use

   Register<IMyType, MyClass>();

Thus your code could be

// IocConfiguration.cs
public static class IocConfiguration
{
    public class Hack { }

    public static void Configure()
    {
        var container = MunqDependencyResolver.Container;
        container.Register<Hack>(ioc => new Hack()).AsRequestSingleton();
        var hack = container.Resolve<Hack>();

        RegisterRepositories(container);
    }

    private static void RegisterRepositories(IocContainer container)
    {
        container.Register<ISomeRepository, SomeRepository>().AsAlwaysNew(); // .AsAlwaysNew() is not required as this is the default
        container.Register<ISomeOtherRepository, SomeOtherRepository>().AsAlwaysNew();
    }
}

I think that you may be using an example from the MVC2 version as a reference.

see http://www.codeproject.com/Articles/176230/Using-Munq-IOC-Container-Version-3-in-ASP-NET-MVC

Matthew

Mar 9, 2012 at 4:59 PM

These seem relevant/related and suggest it might still be a problem relating to event binding at the wrong place in the pipeline, and perhaps also related to access the request context in Application_Start?

http://weblogs.asp.net/reganschroder/archive/2008/07/25/iis7-integrated-mode-request-is-not-available-in-this-context-exception-in-application-start.aspx

http://stackoverflow.com/questions/3712598/httpmodule-init-safely-add-httpapplication-beginrequest-handler-in-iis7-integr

http://stackoverflow.com/questions/536007/ninject-oneperrequestbehaviour-doesnt-seem-to-work-correctly

Mar 9, 2012 at 5:03 PM

Oops, didn't see your comment, I'll take a look at that article as I haven't seen that one before!

Coordinator
Mar 9, 2012 at 5:08 PM

THe artice you pointed me to shows that I do have an error in that I am assuming that HttpContext is available on Application_Start.

This is obviously not an issue in the DevWebServer.  I'll have to delay installing the handler to Dispose of the RequestLifetime object until later.

 

Thanks,

Matthew

Mar 9, 2012 at 5:21 PM

Ok cool, looking forward to your fix!

I've updated my code as suggested so that I don't require a separate ControllerFactory and Controller registrations, so thanks for that!

Coordinator
Mar 9, 2012 at 5:21 PM

From what I see, removing

    var hack = container.Resolve<Hack>();

should make it work.

Now, add it as a depenency on one of your controllers, or its dependencies and see if it works.

 

Matthew

Coordinator
Mar 9, 2012 at 5:31 PM

There really isn't a 'fix'.  Just a constraint that you can't resolve anything with Session, Request, or Cache Lifetime in Application_Start as they all require the current HttpContext.  I'm going to modify the Cache to use the new System.Runtime.Caching support.

I may pull the Session and Request LifetimeManagers form the core to make Munq independent of the System.Web dll and create a Munq.AspnetLifetime.dll

I've run into this issue with the new WebApi and HttpClient which don't use or require System.Web or HttpContext.

Matthew

Apr 17, 2012 at 5:54 AM

Was there a resolution to this issue? I'm having the same problem with trying to use the LifetimeManagers. Everything works as expected if I don't specifiy a Lifetime manager, however if I do use the request lifetime.. I get the same "

No parameterless constructor defined for this object."

Apr 26, 2012 at 8:16 PM

I'm getting the error as well. Cuervomonkey, how did you work around it?

Apr 27, 2012 at 11:46 AM

Unfortunately for you guys I worked around it by switching to Ninject, sorry.

Coordinator
Apr 28, 2012 at 4:49 PM

Sorry guys.  I thought I had fixed this issue, but was still running the dev webserver, not IIS.  When I used IIS Express the error was obvious and repeatable.

I've changed the implementation of the disposer for RequestLifetime objects to use a HttpModule, and to only dispose of objects in the container.

Get V3.1.6 of Munq.IocContainer or 3.1.5 of the Munq.Mvc3 Nuget packages.

I tested with the following changes to a default MVC3 application with Munq.Mvc3 v3.1.6 installed.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
 
namespace MunqRequestLTError
{
	public interface IMyTestClass
	{
		string SayHello();
	}
 
	public class MyTestClass : IMyTestClassIDisposable
	{
 
		public string SayHello()
		{
			return "Hello";
		}
		public void Dispose()
		{
			Dispose(true);
			GC.SuppressFinalize(this);
		}
		protected virtual void Dispose(bool disposing)
		{
			if (disposing)
			{
			}
		}
		~MyTestClass()
		{
			Dispose(false);
		}
	}
}
____________________________________________________
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using Munq;
 
namespace MunqRequestLTError
{
	// 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()
		{
			AreaRegistration.RegisterAllAreas();
 
			RegisterGlobalFilters(GlobalFilters.Filters);
			RegisterRoutes(RouteTable.Routes);
 
			var ioc = Munq.MVC3.MunqDependencyResolver.Container;
			ioc.Register<IMyTestClassMyTestClass>().AsRequestSingleton();
		}
	}
}
_________________________________________________________________________________________________________
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
 
namespace MunqRequestLTError.Controllers
{
	public class HomeController : Controller
	{
		private IMyTestClass _myTestClass;
 
		public HomeController(IMyTestClass myTestClass)
		{
			_myTestClass = myTestClass;
		}
 
		public ActionResult Index()
		{
			ViewBag.Message = _myTestClass.SayHello() + ", Welcome to ASP.NET MVC!";
 
			return View();
		}
 
		public ActionResult About()
		{
			return View();
		}
	}
}
______________________________________________________________________________

Matthew

Aug 9, 2012 at 7:47 AM

I have used the RequestLifeTime before this fix and had no problem. Using Http session lifetime with repositories (especially using IoC and OrM mapped to db) is tricky once. Looking at your code:

 

[InvalidOperationException: Event handlers can only be bound to HttpApplication events during IHttpModule initialization.]

may is due to impedance mismatch. This is frequent happening when object should be created on early bound instead of late binding or data has yet to be fetched completely.  According to Ayende, singleton request usually creates problems for database request when using IoC with OrM. Maybe

 

.AsRequestSingleton();

is the culprit. See my code below which I hope could give some insights for your implementation coz I have don't have much time to review the whole error messages:

 

Architecture 1 :: Class Library ::      DB>>IDB>>Petapoco>>Models>>Object Repository(Implementation)>>IRepository

Architecture 2 :: MVC4 WebAPI ::   Controller>>Resolve IRepository>> Bootstrapper >> MunqRequestLifeTime >> AlwaysNew >> MunqIoC >> Resolve IDB (for petapoco)

File: Bootstrapper.cs used at MVC4 portal section: 

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Http.Controllers;
using Munq;
using Munq.LifetimeManagers;
//using StructureMap;
using GovernmentSurveyDAL.Infrastructures.DBInterfaces;
using GovernmentSurveyDAL.OrM.Petapoco;
using GovernmentSurveyDAL.DataInterfaces;
using GovernmentSurveyDAL.DataConcretes;
using GovernmentSurveyWebServices.Filters;
using GovernmentSurveyWebServices.Selectors;



namespace GovernmentSurveyWebServices.IoC
{
    public static class Bootstrapper
    {
        public static void ConfigureStructureMap()
        {
            //ObjectFactory.Initialize(x => x.AddRegistry<PetaPocoRegistry>());
            //ObjectFactory.Initialize(x => x.AddRegistry<IntegrationTestingRegistry>()); 
        }

        public static IocContainer ConfigureMunqAlwaysNewLifeTime()
        {
            var IoCAlwaysNew = new IocContainer();
            //Lifetime is always new for DB context to avoid lifetime mismatch. CLR 
            //create object will take around 0.0000006 sec. Refer to Rob Connery's and Ayende discussion
            //during code review for MVC1 StoreFront videos. I thinks video session no. 15 when they are dicussing using structureMap

            ILifetimeManager lifetime = new Munq.LifetimeManagers.AlwaysNewLifetime();
            IoCAlwaysNew.UsesDefaultLifetimeManagerOf(lifetime);
            IoCAlwaysNew.Register<IDatabase>(x => new Database("your_db_name"));

            return IoCAlwaysNew;
        }

        public static IocContainer ConfigureMunqContainerLifeTime()
        {
            var DBContainer = ConfigureMunqAlwaysNewLifeTime();
            ILifetimeManager lifetime = new Munq.LifetimeManagers.ContainerLifetime();
            var IoCContainerLifetime = new IocContainer();
            IoCContainerLifetime.UsesDefaultLifetimeManagerOf(lifetime);

            IoCContainerLifetime.Register<IWriteDemographics>
                (x => new WriteDemographicsV1(DBContainer.Resolve<IDatabase>()));
            IoCContainerLifetime.Register<IReadDemographics>
                (x => new ReadDemographicsV1(DBContainer.Resolve<IDatabase>()));

            IoCContainerLifetime.Register<IWriteSurveysMOH>
                (x => new WriteSurveysMOH(DBContainer.Resolve<IDatabase>()));
            IoCContainerLifetime.Register<IReadSurveysMOH>
                (x => new ReadSurveysMOH(DBContainer.Resolve<IDatabase>()));


            return IoCContainerLifetime;

        }

        //move to Application_Start at Global.asax.cs
        //public static IocContainer ConfigureMunqApplicationStart()
        //{
        //    ILifetimeManager lifetime = new Munq.LifetimeManagers.ContainerLifetime();
        //    var IoCContainerAppStart = new IocContainer();
        //    IoCContainerAppStart.UsesDefaultLifetimeManagerOf(lifetime);

        //    IoCContainerAppStart.Register<IHttpActionSelector>(x => new CorsPreflightActionSelector());
        //    return IoCContainerAppStart;
        //}
        
    }
}

At controller level:

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Formatting;
using System.Web.Http;

using System.Web.Http.Controllers; //add this for CORS
using GovernmentSurveyDAL.DataInterfaces;
using GovernmentSurveyDAL.Models;
using GovernmentSurveyDAL.BizModels.Listings;

using Munq;
using GovernmentSurveyWebServices.IoC;
using GovernmentSurveyWebServices.Filters;//add this for CORS
using GovernmentSurveyWebServices.Selectors;//add this for CORS beta method

namespace GovernmentSurveyWebServices.Controllers
{
    [HttpControllerConfiguration(HttpActionSelector = typeof(CorsActionSelector))] //add this for CORS beta method
    public class SurveysMOHController : ApiController
    {

        IReadSurveysMOH _contextRead;
        IWriteSurveysMOH _contextWrite;

        public SurveysMOHController()
        {
            IocContainer _ioc = Bootstrapper.ConfigureMunqContainerLifeTime();
            _contextRead = _ioc.Resolve<IReadSurveysMOH>();
            _contextWrite = _ioc.Resolve<IWriteSurveysMOH>();
        }

        [AcceptVerbs("GET", "HEAD")]
        [EnableCors]
        public IQueryable<SurveyType> SurveyTypes()
        {
            try
            {
                var _results = _contextRead.GetAllSurveyTypes();
                return _results;
            }
            catch (Exception)
            {
                var exceptionResponse = new HttpResponseMessage(HttpStatusCode.InternalServerError)
                {
                    Content = new StringContent("Internal Server Error.")
                };

                throw new HttpResponseException(exceptionResponse);
            }
        }
......

At Object repository:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using GovernmentSurveyDAL.Models;
using GovernmentSurveyDAL.BizModels.Listings;
using GovernmentSurveyDAL.DataInterfaces;
using GovernmentSurveyDAL.Infrastructures.DBInterfaces;
using GovernmentSurveyDAL.OrM.Petapoco;

namespace GovernmentSurveyDAL.DataConcretes
{
    public class ReadSurveysMOH : IReadSurveysMOH
    {
        private readonly IDatabase _db;
        public ReadSurveysMOH(IDatabase dataContext)
        {
            _db = dataContext;
        }

        #region survey type
        public IQueryable<SurveyType> GetAllSurveyTypes()
        {
            var results = _db.Fetch<SurveyType>().AsQueryable();
            return results;
        }

        public SurveyType GetSurveyTypeById(int surveyTypeId)
        {
            var result = _db.First<SurveyType>("SELECT * FROM SurveyType WHERE Id=@0", surveyTypeId);
            return result;
        }
        #endregion
........

 At Interface Level:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using GovernmentSurveyDAL.Models;
using GovernmentSurveyDAL.BizModels.Listings;

namespace GovernmentSurveyDAL.DataInterfaces
{
    public interface IReadSurveysMOH
    {
........

        //surveys types
        IQueryable<SurveyType> GetAllSurveyTypes();
        SurveyType GetSurveyTypeById(int surveyTypeId);

       
.......

        bool IfExist<T>(int idTocheck);
        bool IfExist<T>(string idTocheck);
        
    }



This is not the best solution but I managed to make it work smoothly without worrying about impedance mismatch.
My controller is quite clean and my views are both at portal and mobile devices. Using shared hosting... Munq is really fast. Hope
the above could help and remember Singleton should be used after really sure about object creation and Http propagation.

 

 

 

 

Nov 28, 2012 at 2:58 AM

yes