Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>First, thanks for the link to the post <a href="http://lostechies.com/jimmybogard/2013/10/29/put-your-controllers-on-a-diet-gets-and-queries/">"Put your controllers on a diet: GETs and queries"</a>. My code example uses types from it.</p> <p>My solution <strong>also involves usage of action filters</strong> as point to inject generic behaviour.</p> <p>Controller is simple enough and looks like @Kambiz Shahim's:</p> <pre><code>[QueryFilter] public class ConferenceController : Controller { public ActionResult Index(IndexQuery query) { return View(); } public ViewResult Show(ShowQuery query) { return View(); } public ActionResult Edit(EditQuery query) { return View(); } } </code></pre> <p>Working on <code>QueryFilterAttribute</code> I realised that <strong><code>IMediator</code> and its implementation can be omitted. It is enough to know type of query to resolve an instance of <code>IQueryHandler&lt;,&gt;</code> via IoC.</strong></p> <p>In my example <a href="http://docs.castleproject.org/Windsor.MainPage.ashx">Castle Windsor</a> and implementation of <a href="http://blog.ploeh.dk/2010/02/03/ServiceLocatorisanAnti-Pattern/">'Service Locator'</a> pattern are used.</p> <pre><code>public class QueryFilterAttribute : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { base.OnActionExecuting(filterContext); object query = filterContext.ActionParameters["query"]; Type queryType = query.GetType(); Type modelType = queryType.GetInterfaces()[0].GetGenericArguments()[0]; var handlerType = typeof(IQueryHandler&lt;,&gt;).MakeGenericType(queryType, modelType); // Here you should resolve your IQueryHandler&lt;,&gt; using IoC // 'Service Locator' pattern is used as quick-and-dirty solution to show that code works. var handler = ComponentLocator.GetComponent(handlerType) as IQueryHandler; var model = handler.Handle(query); filterContext.Controller.ViewData.Model = model; } } </code></pre> <p><code>IQueryHandler</code> interface is added to avoid working with Reflection</p> <pre><code>/// &lt;summary&gt; /// All derived handlers can be refactored using generics. But in the real world handling logic can be completely different. /// &lt;/summary&gt; /// &lt;typeparam name="TQuery"&gt;The type of the query.&lt;/typeparam&gt; /// &lt;typeparam name="TResponse"&gt;The type of the response.&lt;/typeparam&gt; public interface IQueryHandler&lt;in TQuery, out TResponse&gt; : IQueryHandler where TQuery : IQuery&lt;TResponse&gt; { TResponse Handle(TQuery query); } /// &lt;summary&gt; /// This interface is used in order to invoke 'Handle' for any query type. /// &lt;/summary&gt; public interface IQueryHandler { object Handle(object query); } /// &lt;summary&gt; /// Implements 'Handle' of 'IQueryHandler' interface explicitly to restrict its invocation. /// &lt;/summary&gt; /// &lt;typeparam name="TQuery"&gt;The type of the query.&lt;/typeparam&gt; /// &lt;typeparam name="TResponse"&gt;The type of the response.&lt;/typeparam&gt; public abstract class QueryHandlerBase&lt;TQuery, TResponse&gt; : IQueryHandler&lt;TQuery, TResponse&gt; where TQuery : IQuery&lt;TResponse&gt; { public abstract TResponse Handle(TQuery query); object IQueryHandler.Handle(object query) { return Handle((TQuery)query); } } </code></pre> <p>Types should be registered <code>in Global.asax.cs</code></p> <pre><code> container.Register(Component.For&lt;ISession&gt;().ImplementedBy&lt;FakeSession&gt;()); container.Register( Classes.FromThisAssembly() .BasedOn(typeof(IQueryHandler&lt;,&gt;)) .WithService.Base() .LifestylePerWebRequest()); </code></pre> <p>There is a <a href="https://gist.github.com/ilyapalkin/c82904208bd529814713"><strong>link to gist on github</strong></a> with all code.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload