AOP: пользовательский атрибут связывателя модели, использующий Ninject - PullRequest
0 голосов
/ 11 апреля 2011

Вкратце: я пытаюсь создать пользовательский механизм связывания моделей, который будет принимать тип пользователя и получать его идентификатор, а затем использовать класс обслуживания для извлечения строго типизированного объекта.

Если естьлучший способ сделать это, пожалуйста, дайте мне знать.

Elabaration:

У меня есть ненагруженная настройка со всеми моими привязками на моем уровне DomainService, 3 веб-интерфейса подключены к уровню службы домена.Каждое приложение asp.net mvc загружает привязки в ядро.

// мой пользовательский связыватель модели

public class UserModelBinder : IModelBinder
    {
        private IAuthenticationService auth;

        public UserModelBinder(IAuthenticationService _auth, EntityName type, 
        string loggedonuserid)
        {
            this.auth = _auth;
            CurrentUserType = type;
            CurrentUserId = loggedonuserid;
        }


        public EntityName CurrentUserType { get; private set; }
        private string CurrentUserId {  get; set; }

        public object BindModel(ControllerContext controllerContext, 
        ModelBindingContext bindingContext)
        {
            object loggedonuser = null;

            if (CurrentUserType == EntityName.Client)
                loggedonuser = GetLoggedOnClientUser(CurrentUserId);
            else if (CurrentUserType == EntityName.Shop)
                loggedonuser = GetLoggedOnShopUser(CurrentUserId);
            else
                throw new NotImplementedException();

            return loggedonuser;
        }

        public ClientUser GetLoggedOnClientUser(string loggedonuserid)
        {
            var user = _auth.GetLoggedOnClientUser(loggedonuserid);
            if (user == null)
                throw new NoAccessException();

            return user;
        }

        public ShopUser GetLoggedOnShopUser(string loggedonuserid)
        {
            var user = _auth.GetLoggedOnShopUser(loggedonuserid);
            if (user == null)
                throw new NoAccessException();

            return user;
        }

    }

мой Global.aspx.cs

// using NInject to override application started
        protected override void OnApplicationStarted()
        {
            AreaRegistration.RegisterAllAreas();
            // hand over control to NInject to register all controllers
            RegisterRoutes(RouteTable.Routes);



 //how do I instantiate?
            ModelBinders.Binders.Add(typeof(object), new 
            UserModelBinder(null,EntityName.Client, User.Identity.Name));

        }

Моя проблема в том, что IAuthentication - это служба, она связана с другими вещамикак хранилище, как я могу на самом деле создать это правильно?Должен ли я создать новый модуль NinjectModule?Я действительно смущен этим, поэтому любая помощь очень ценится.Я пытался перейти в Container.Get ();- но это ноль ...

ПРИМЕЧАНИЕ: причина, по которой я создаю связыватель моделей - все контроллеры будут требовать типа пользователя, поскольку мой уровень обслуживания требует, какой тип пользователя делает запрос, большинство методовв моем слое обслуживания будут перегрузки, когда он будет делать что-то для ShopUser или ClientUser или любого другого пользователя в системе ...

EDIT : я мог бы очень легко выполнить вызов контроллерана IAuthenticationService и получить тип пользователя и перейти на мой уровень domainservice для обработки соответствующих задач, но я просто хочу знать, как это возможно с ModelBindings (и если это имеет смысл сделать это таким образом).

Edit2: есть ли рабочий пример использования пользовательского атрибута с AOP с пользовательским атрибутом, вызывающим / связывающим / получающим экземпляр ISomethingService?

1 Ответ

0 голосов
/ 11 апреля 2011

Вы можете использовать шаблон Service Locator здесь.Передайте Ninject Container (IKernel?) В конструктор и разрешите AuthenticationService каждый раз, когда вам нужно что-то связать.

Уточнение этого может заключаться в том, чтобы иметь аргумент конструктора Func, где вы передаете функцию для разрешения службы,Это было бы более явно и удаляет зависимость от Ninject.Как то так:

public class MyModelBinder : IModelBinder
{
    Func<IAuthenticationService> _resolveAuthService;

    public MyModelBinder(Func<IAuthenticationService> resolveAuthService)
    {
         _resolveAuthService = resolveAuthService;
    }

    public override object Bind(Context c)
    {
        var authService = _resolveAuthService();

        authService.GetSomething();

        // etc...
    }
}
...