Рефакторинг, если в цепочке ответственности образец


Я пытался изучать различные паттерны программирования, и "цепочку ответственности" как-то ускользает от меня. Мне сказали, что мой конкретный фрагмент кода будет хорошим кандидатом на цепь ответственности, и я интересно, если кто-то может показать мне, как туда добраться?

Public Overrides Sub OnActionExecuting(ByVal filterContext As ActionExecutingContext)

    ''# Set a local variable for the HttpContext.Request. This is going to
    ''# be used several times in the subsequent actions, so it needs to be
    ''# at the top of the method.
    Dim request = filterContext.HttpContext.Request
    Dim url As Uri = request.Url

    ''# Now we get the referring page
    Dim referrer As Uri = If(Not request.UrlReferrer Is Nothing, request.UrlReferrer, Nothing)

    ''# If the referring host name is the same as the current host name,
    ''# then we want to get out of here and not touch anything else. This
    ''# is because we've already set the appropriate domain in a previous
    ''# call.
    If (Not referrer Is Nothing) AndAlso
       (Not url.Subdomain = "") AndAlso
       (Not url.Subdomain = "www") AndAlso
       (referrer.Host = url.Host) Then
        Return
    End If

    ''# If we've made it this far, it's because the referring host does
    ''# not match the current host. This means the user came here from
    ''# another site or entered the address manually.  We'll need to hit
    ''# the database a time or two in order to get all the right
    ''# information.

    ''# This is here just in case the site is running on an alternate
    ''# port. (especially useful on the Visual Studio built in web server
    ''# / debugger)
    Dim newPort As String = If(url.IsDefaultPort, String.Empty, ":" + url.Port.ToString())

    ''# Initialize the Services that we're going to need now that we're
    ''# planning on hitting the database.
    Dim RegionService As Domain.IRegionService = New Domain.RegionService(New Domain.RegionRepository)

    ''# Right now we're getting the requested region from the URI.  This
    ''# is when a user requests something like
    ''# http://calgary.example.com, whereby we extract "calgary" out of
    ''# the address.
    Dim region As Domain.Region = RegionService.GetRegionByName(url.Subdomain)

    ''# If the RegionService returned a region from it's query, then we
    ''# want to exit the method and allow the user to continue on using
    ''# this region.
    If Not region Is Nothing Then
        Return
    End If

    ''# If we've made it this far, it means that the user either entered
    ''# an Invalid Region (yes, we already know the region is invalid) or
    ''# used www. or nothing as a subdomain.  Up until this point, we
    ''# haven't cared if the user is authenticated or not, nor have we
    ''# cared what the full address in their address bar is.  Now we're
    ''# probably going to start redirecting them somewhere.

    ''# First off we need to check if they're authenticated users. If they
    ''# are, we'll just send them on over to their default region.
    If filterContext.HttpContext.User.Identity.IsAuthenticated Then
        Dim userService As New Domain.UserService(New Domain.UserRepository)
        Dim userRegion = userService.GetUserByID(AuthenticationHelper.RetrieveAuthUser.ID).Region.Name

        filterContext.HttpContext.Response.Redirect(url.Scheme + "://" + userRegion + "." + url.PrimaryDomain + newPort + request.RawUrl)

    End If


    ''# Now we know that the user is not Authenticated. So here we check for
    ''# www. If the host has www in it, then we just strip the www and
    ''# bounce the user to the original request.
    If request.Url.Host.StartsWith("www") Then
        Dim newUrl As String = url.Scheme + "://" + url.Host.Replace("www.", "") + newPort + request.RawUrl
        ''# The redirect is permanent because we NEVER want to see www in the domain.
        filterContext.HttpContext.Response.RedirectPermanent(newUrl)

        ''# It's ok for an annonymous browser to view the "Details" of an
        ''# Event/User/Badge/Tag without being assigned to a regions. So
        ''# this is why we strip the www but don't redirect the visitor
        ''# directly over to the "Choose Your Region" view.

    End If

    ''# If we've gone this far, we know the region is invalid, and the
    ''# user needs to be directed to a "choose your region" page.  We're
    ''# not going to do the redirecting here because we want to allow for
    ''# browsing to specific Users/Tags/Badges/Events that are Region
    ''# Agnostic. But if a user tries to view an event listing of any
    ''# sort, we're going to fire them over to the "Choose Your Region"
    ''# page via a separate Attribute attached to only the Actions that
    ''# require it.

End Sub

Вот комментарии версия для C#:

public override void OnActionExecuting(ActionExecutingContext filterContext)
{
    var request = filterContext.HttpContext.Request;
    Uri url = request.Url;
    Uri referrer = (request.UrlReferrer != null) ? request.UrlReferrer : null;



    if (((referrer != null)) && (!string.IsNullOrEmpty(url.Subdomain)) && (!(url.Subdomain == "www")) && (referrer.Host == url.Host)) {
        return;
    }


    string newPort = url.IsDefaultPort ? string.Empty : ":" + url.Port.ToString();


    Domain.IRegionService RegionService = new Domain.RegionService(new Domain.RegionRepository());
    Domain.Region region = RegionService.GetRegionByName(url.Subdomain);


    if ((region != null)) {
        return;
    }


    if (filterContext.HttpContext.User.Identity.IsAuthenticated) {
        Domain.UserService userService = new Domain.UserService(new Domain.UserRepository());
        dynamic userRegion = userService.GetUserByID(AuthenticationHelper.RetrieveAuthUser.ID).Region.Name;

        filterContext.HttpContext.Response.Redirect(url.Scheme + "://" + userRegion + "." + url.PrimaryDomain + newPort + request.RawUrl);

    }




    if (request.Url.Host.StartsWith("www")) {
        string newUrl = url.Scheme + "://" + url.Host.Replace("www.", "") + newPort + request.RawUrl;
        //'# The redirect is permanent because we NEVER want to see www in the domain.
        filterContext.HttpContext.Response.RedirectPermanent(newUrl);

    }


}


870
1
задан 20 августа 2011 в 02:08 Источник Поделиться
Комментарии
1 ответ

Этот метод не является хорошим кандидатом для шаблон цепочка ответственности, но это наверняка можно реализовать с помощью его (только для образовательных целей):

    public override void OnActionExecuting(ActionExecutingContext filterContext)
{
//Init
var referrerRequestHandler = new ReferrerRequestHandler();
var regionRequestHandler = new RegionRequestHandler();
var authenticatedRequestHandler = new AuthenticatedRequestHandler(filterContext);
var wwwRequestHandler = new WwwRequestHandler(filterContext);

referrerRequestHandler.SetNextHandler(regionRequestHandler);
regionRequestHandler.SetNextHandler(authenticatedRequestHandler);
authenticatedRequestHandler.SetNextHandler(wwwRequestHandler);

//Run
var request = filterContext.HttpContext.Request;
referrerRequestHandler.Redirect(request);
}

    public abstract class RequestHandler
{
public void SetNextHandler(RequestHandler nextHandler)
{
_nextHandler = nextHandler;
}

public void Redirect(HttpRequestBase request)
{
bool handeled = HandleRedirect(request);
if (!handeled)
{
if (_nextHandler != null)
{
_nextHandler.Redirect(request);
}
}
}

protected abstract bool HandleRedirect(HttpRequestBase request);

private RequestHandler _nextHandler;
}

    public class ReferrerRequestHandler : RequestHandler
{
protected override bool HandleRedirect(HttpRequestBase request)
{
Uri url = request.Url;
Uri referrer = (request.UrlReferrer != null) ? request.UrlReferrer : null;
if (((referrer != null)) && (!string.IsNullOrEmpty(url.Subdomain)) && (!(url.Subdomain == "www")) && (referrer.Host == url.Host))
{
return true;
}
else
{
return false;
}
}
}

    public class RegionRequestHandler: RequestHandler
{
protected override bool HandleRedirect(HttpRequestBase request)
{
Domain.IRegionService RegionService = new Domain.RegionService(new Domain.RegionRepository());
Domain.Region region = RegionService.GetRegionByName(url.Subdomain);
if ((region != null))
{
return true;
}
else
{
return false;
}
}
}

    public class AuthenticatedRequestHandler: RequestHandler
{
public AuthenticatedRequestHandler(ActionExecutingContext filterContext)
{
_filterContext = filterContext;
}

protected override bool HandleRedirect(HttpRequestBase request)
{
Uri url = request.Url;
string newPort = url.IsDefaultPort ? string.Empty : ":" + url.Port.ToString();
if (_filterContext.HttpContext.User.Identity.IsAuthenticated)
{
Domain.UserService userService = new Domain.UserService(new Domain.UserRepository());
dynamic userRegion = userService.GetUserByID(AuthenticationHelper.RetrieveAuthUser.ID).Region.Name;
_filterContext.HttpContext.Response.Redirect(url.Scheme + "://" + userRegion + "." + url.PrimaryDomain + newPort + request.RawUrl);
return true;
}
else
{
return false;
}
}

private readonly ActionExecutingContext _filterContext;
}

    public class WwwRequestHandler : RequestHandler
{
public WwwRequestHandler(ActionExecutingContext filterContext)
{
_filterContext = filterContext;
}

protected override bool HandleRedirect(HttpRequestBase request)
{
Uri url = request.Url;
if (request.Url.Host.StartsWith("www"))
{
string newUrl = url.Scheme + "://" + url.Host.Replace("www.", "") + newPort + request.RawUrl;
//'# The redirect is permanent because we NEVER want to see www in the domain.
_filterContext.HttpContext.Response.RedirectPermanent(newUrl);
return true;
}
else
{
return false;
}
}
private readonly ActionExecutingContext _filterContext;
}

2
ответ дан 20 августа 2011 в 03:08 Источник Поделиться