AOP:使用 Ninject 自定义模型绑定器属性
简而言之:我正在尝试创建一个自定义模型绑定器,它将接受用户类型并获取他们的 ID,然后使用服务类来检索强类型对象。
如果有更好的方法来做到这一点,请告诉我。
详细说明:
我在 DomainService 层中对所有绑定进行了 ninject 设置,3 个 Web ui 连接到域服务层。每个 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;
}
}
my 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 或系统中的任何其他用户做一件事...
编辑: 我可以在我的控制器中非常轻松地调用 IAuthenticationService 并获取用户类型并传递到我的域服务层来处理相关任务,但我只想知道 ModelBindings 是如何实现的(以及这样做是否有意义)那样)。
Edit2:是否有使用带有 AOP 的自定义属性以及调用/绑定/获取 ISomethingService 实例的自定义属性的工作示例?
In short: I am trying to create a custom model binder that will take in the type of user and get their id, then use a service class to retrieve the strongly typed object.
If there is a better way to do this, please let me know.
Elabaration:
I have ninject setup with all my bindings within my DomainService layer, 3 web ui's are hooked up to the domain service layer. Each asp.net mvc app loads the bindings into the kernal.
//my custom model binder
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;
}
}
my 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));
}
My problem is IAuthentication is a service, it is connected to other things like a repository, how do I actually instantiate this properly? Should I create a new NinjectModule? I am really confused with this so any help is greatly appreciated. I have tried to pass in Container.Get(); - but it is null...
NOTE: the reason why I am creating a modelbinder- all controllers will require the type of user as I my service layer requires which type of user is making a request, most methods in my service layer will have overloads where it will do one thing for a ShopUser or ClientUser or any other user in the system...
EDIT:
I could very easiy within my controller call upon the IAuthenticationService and get the type of user and pass into my domainservice layer to process the relevant tasks but I just want to know how it is possible with the ModelBindings (and if it makes sense to do it that way).
Edit2: Is there a working sample of using a custom Attribute with AOP with the custom attribute calling/binding/getting an instance of ISomethingService?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您可以在此处使用服务定位器模式。将 Ninject 容器(IKernel?)传递给构造函数,并在每次需要绑定某些内容时解析 AuthenticationService。
对此的改进可能是有一个构造函数参数 Func,您可以在其中传递函数来解析服务。这会更加明确,并且消除了对 Ninject 的依赖。像这样的东西:
You can use the Service Locator pattern here. Pass the Ninject Container (IKernel?) to the constructor and resolve the AuthenticationService each time you need to bind something.
A refinement of this could be to have a constructor argument Func where you pass the function to resolve the service. This would be more explicit and removes the dependency on Ninject. Something like this: