1

In asp.net MVC, dependency injection with controllers is simple and straightforward. Now, I'd like to remove most of the logic from views by using helpers. The problem is that these helpers use some of the objects that are injected.

Let me write an example:

public interface ISessionData
{
  List<string> IdList {get;}
}

public MyController : Controller
{

  public MyController(ISessionData sessionData)
  {
    ...
  }
}

session data is injected into controller. So far so good. But now I have a helper. Let's say it looks like this:

 public class MyHelper
    {
        private readonly ISessionData sessionData;

        public MyHelper(ISessionData sessionData)
        {
            this.sessionData = sessionData;
        }

        public bool CheckSomethingExistsInSession(string id)
        {
            return sessionData.IdList.Any(x => x.Id.Equals(id));
        }
}

Now what? I'd like MyHelper to be injected into view. Only way I can see is adding this helper to model and passing it to view every time. Any other ideas?

2 Answers 2

3

In MVC it is better to pass ISessionData data from Controller to View (using ViewModel or ViewData):

ViewData["Session"] = sessionData.IdList.ToList();

And remove ISessionData dependency from the helper. Something like this:

public class MyHelper
{
    //private readonly ISessionData sessionData;

    public MyHelper(/*ISessionData sessionData*/)
    {
        //this.sessionData = sessionData;
    }

    public bool CheckSomethingExistsInSession(string id, IList<...> sessionData)
    {
        return sessionData.Any(x => x.Id.Equals(id));
    }
}

In View:

<% var somethingExists = new MyHelper().CheckSomethingExistsInSession(
    1, ViewData["Session"] as IList<...>); %>

UPDATED:

public static class MyHelper
{
    public static bool CheckSomethingExistsInSession(string id, IList<...> sessionData)
    {
        return sessionData.Any(x => x.Id.Equals(id));
    }
}

<% var somethingExists = MyHelper.CheckSomethingExistsInSession(
    1, ViewData["Session"] as IList<...>); %>
Sign up to request clarification or add additional context in comments.

Comments

0

You should remove session logic from your controller's constructor and insert it into the controllers action method by using an IModelBinder. See below:

public class SessionDataModelBinder : IModelBinder
{
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        // Get/create session data implementating ISeesionData or whatever here. This will be return to the controller action method.
        return new SessionData()
    }
}

On you controller you would do something like:

public MyController : Controller        
{        

    public MyController()
    {               
        ....
    }

    public ActionResult Index(ISessionData sessionData)
    {
         // do stuff with ISessionData.

         // Redirect or whatever.
         return this.RedirectToAction("Index");
    }
}

You need to add your IModelBinder like below for it to be called. You can do this in the http application's startup.

System.Web.Mvc.ModelBinders.Binders[typeof(ISessionData)] = new SessionDataModelBinder();

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.