Выполнение операций регистрации в MVC .NET - PullRequest
2 голосов
/ 01 сентября 2009

Я пытаюсь найти лучший способ для входа в приложение, которое я сейчас разрабатываю.

сейчас у меня есть таблица журнала, в которой хранятся имя пользователя, отметка времени, действие, контроллер и сообщение. когда создается экземпляр контроллера, он получает информацию о IoC через Castle Windsor.

например, мой контроллер "Сайты" создается следующим образом:

    private ISitesRepository siteRepository;
    private ILogWriter logWriter;

    public SiteController(ISitesRepository siteRepository, ILogWriter logWriter)
    {
        this.siteRepository = siteRepository;
        this.logWriter = logWriter;
    }

и средство записи журнала имеет функцию, которая создает и вставляет запись журнала (WriteToLog). в действиях Edit и Create контроллера Sites он вызывает функцию WriteToLog.

это работает и выполняет свою работу, но мой вопрос - действительно ли мне нужно настроить каждый контроллер таким образом, проходя через интерфейс / репозиторий ILogWriter? меня поразило, что я мог бы настроить LogController и просто сделать это "тяжелой работой" записи в мои журналы.

Таким образом, мне не пришлось бы связываться с IoC в каждом другом контроллере. Можно ли выполнить действие на другом контроллере (например, LogController-> WriteLog)? я не уверен, как это будет сделано без перенаправления ...

Ответы [ 2 ]

1 голос
/ 02 сентября 2009

Хорошо, после сильной царапины на голове, я думаю, что нашел приемлемое решение.

Я реализовал свое действие регистрации как фильтр настраиваемого действия следующим образом:

public class LogAction : ActionFilterAttribute, IActionFilter
{
    public LogLevel loglevel;
    public string message;


    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        ILogWriter logWriter = AppServiceFactory.Instance.Create<ILogWriter>();

        logWriter.WriteToLog(
          filterContext.ActionDescriptor.ControllerDescriptor.ControllerName, 
          filterContext.ActionDescriptor.ActionName,
          loglevel,
          filterContext.HttpContext.Timestamp,
          filterContext.HttpContext.User.Identity.Name.ToString(),
          message + "(id=" + filterContext.RouteData.Values["id"] + ")");
    }

}

но я наткнулся на стену, пытаясь заставить IoC работать в фильтре пользовательских атрибутов. изучив stackoverflow и поиски в Google, я обнаружил, что это довольно сложно сделать с разговорами об использовании различных оболочек, активаторов действий и т. д., которые кажутся более сложными, чем я действительно хотел иметь дело.

пытаясь узнать больше об IoC (я все еще новичок в этом), я нашел эту статью , что действительно помогло направить меня в правильном направлении. я добавил его запечатанный класс AppServiceFactory с моим WindsorControllerFactory, и он работал как шарм.

Как я уже сказал, я новичок в MVC и в этом IoC, поэтому я не уверен, что это идеальный способ обработки вещей, но он кажется простым и работает до сих пор. Я приветствовал бы любые комментарии или критику относительно обработки этого через этот метод.

UPDATE Выяснил другой способ сделать это - создал функцию в моем проекте WebUI следующим образом:

public static class Loggers
{
    public static void WriteLog(ControllerContext controllerContext, LogLevel logLevel, string message)
    {
        ILogWriter logWriter = AppServiceFactory.Instance.Create<ILogWriter>();
        logWriter.WriteToLog(
            controllerContext.RouteData.Values["controller"].ToString(),
            controllerContext.RouteData.Values["action"].ToString(),
            logLevel,
            controllerContext.HttpContext.Timestamp,
            controllerContext.HttpContext.User.Identity.Name.ToString(),
            message);
    }
}

Теперь, куда бы я ни захотел что-то записать, я могу позвонить

            Loggers.WriteLog(
            this.ControllerContext,
            LogLevel.Membership,
            "Removed role '" + role + "'" + " from user " + _userService.Get(id).UserName );

записать запись в журнал. это дает мне гораздо большую гибкость в отношении содержимого моего «сообщения» и решает проблему включения регистрации в файле global.asax, что было бы сложно, если не невозможно, с помощью фильтров атрибутов. я оставлю все остальное, поскольку это может быть полезно кому-то еще, но я думаю, что именно так я и поступлю.

как обычно, в MVC все обычно проще, чем я думаю, оригинально:)

1 голос
/ 01 сентября 2009

Не могли бы вы пройти мимо абстрактного класса? Этот абстрактный класс, имеющий статическое свойство, ссылающееся на вас, пишущий журнал?

как то так

public abstract class BaseController
{
    public static ILogWriter Logwriter{get;set;}
    public static BaseController
    {
        Logwriter = YourFactory.GetLogwriter();
    }
}

public class YourController:BaseController
{
    public YourController(ISitesRepository siteRepository)
    {
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...