tutorial quickly por impulsado driven dominio domain diseño development ddd capas capa aplicacion c# .net domain-driven-design n-tier

c# - quickly - Cómo pasar la información del usuario actual a todas las capas en DDD



domain drive development (2)

He hecho este tipo de cosas antes de usar IoC. El beneficio de esto es que es muy comprobable: puede eliminar su información de usuario para la prueba, y es razonablemente legible y fácil de seguir.

Preguntas similares se han hecho antes, pero no exactamente lo mismo (a menos que lo haya perdido)

Quiero pasar la instancia de la clase IUserInfo a través de mi Servicio, Dominio, Eventos de dominio, Controladores de eventos de dominio ...

Cuál es la mejor manera de hacerlo.

Debería

  • Inyecte utilizando IoC registrándolo en la instancia de Httpcontext.Current.session ["CurrentUser"];

  • Agregue los datos al hilo actual.

  • Cualquier otra forma

Estoy atascado en los manejadores de eventos de dominio, donde quiero usar los datos para la auditoría, así como para enviar correos electrónicos.

Quiero poder usar la información de CurrentUser desde casi cualquier lugar de mi aplicación.

Con los subprocesos, ya que los subprocesos se agrupan, soy escéptico si la reutilización de los subprocesos restablecerá los datos. Si no, dime cómo usar el subproceso para pasar la instancia de IUser.

Saludos,

mar


Puede que mi enfoque no sea el ideal, pero me parece que funciona bastante bien. Cosa de lo que hice: decidí no usar la inyección de dependencia pasar al usuario actual en todas partes directamente porque se estaba volviendo demasiado incómodo y cambié a contexto estático. Problema con los contextos - son un poco difíciles de manejar.

Este está definido en mi dominio:

public static class UserContext{ private static Func<User> _getCurrentUser; private static bool _initialized; public static User Current{ get{ if(!_initialized) throw new Exception("Can i haz getCurrentUser delegate?"); var user=_getCurrentUser(); return user??User.Anonymous; } } public static void Initialize(Func<User> getCurrentUser){ _getCurrentUser=getCurrentUser; _initialized=true; } }

Tenga en cuenta que el delegado es estático: para toda la aplicación solo una a la vez. Y no estoy 100% seguro de su ciclo de vida, posibles fugas de memoria o todo eso.

La aplicación del cliente es responsable de inicializar el contexto. Mi aplicación web hace eso en cada solicitud:

public class UserContextTask:BootstrapperTask{ private readonly IUserSession _userSession; public UserContextTask(IUserSession userSession){ Guard.AgainstNull(userSession); _userSession=userSession; } public override TaskContinuation Execute(){ UserContext.Initialize(()=>_userSession.GetCurrentUser()); return TaskContinuation.Continue; } }

Uso de la biblioteca mvcextensions para alinear las tareas de arranque. Solo puede suscribirse para los eventos correspondientes en global.asax para eso.

En el lado del cliente (aplicación web), implemento un servicio de aplicación llamado IUserSession :

public User GetCurrentUser(){ if(HttpContext.Current.User==null) return null; var identity=HttpContext.Current.User.Identity; if(!identity.IsAuthenticated) return null; var user=_repository.ByUserName(identity.Name); if(user==null) throw new Exception("User not found. It should be. Looks bad."); return user; }

Hay un poco más de código cojo necesario para usar formularios de autenticación con roles sin proveedor de membresía y proveedor de rol. Pero ese no es el punto de esta pregunta.

A nivel de dominio: describo explícitamente los permisos que los usuarios podrían tener como este:

public class AcceptApplications:IUserRights{ public bool IsSatisfiedBy(User u){ return u.IsInAnyRole(Role.JTS,Role.Secretary); } public void CheckRightsFor(User u){ if(!IsSatisfiedBy(u)) throw new ApplicationException ("User is not authorized to accept applications."); } }

Lo bueno es que esos permisos se pueden hacer más sofisticados. P.ej:

public class FillQualityAssessment:IUserRights{ private readonly Application _application; public FillQualityAssessment(Application application){ Guard.AgainstNull(application, "User rights check failed. Application not specified."); _application=application; } public bool IsSatisfiedBy(User u){ return u.IsInRole(Role.Assessor)&&_application.Assessors.Contains(u); } public void CheckRightsFor(User u){ if(!IsSatisfiedBy(u)) throw new ApplicationException ("User is not authorized to fill quality assessment."); } }

Los permisos también se pueden verificar vica versa: el usuario tiene estos amigos:

public virtual bool HasRightsTo<T>(T authorizationSpec) where T:IUserRights{ return authorizationSpec.IsSatisfiedBy(this); } public virtual void CheckRightsFor<T>(T authorizationSpec) where T:IUserRights{ authorizationSpec.CheckRightsFor(this); }

Aquí está mi clase base raíz agregada:

public class Root:Entity,IRoot{ public virtual void Authorize(IUserRights rights){ UserContext.Current.CheckRightsFor(rights); } }

Y así es como verifico los permisos:

public class Application{ public virtual void Accept(){ Authorize(new AcceptApplications()); OpeningStatus=OpeningStatus.Accepted; } }

Espero que eso ayude...