asp.net mvc中的依赖注入模型

本文关键字:依赖 注入 模型 net mvc asp | 更新日期: 2023-09-27 18:11:58

我目前正在开发一个。net MVC 5站点,我有一个关于提高质量的问题。我从另一个开发人员那里接手了这个项目,整个项目都有相当多的代码气味,所以我正在努力清理这个项目。我遇到的问题是大量的类耦合,从而导致低内聚。(为开发人员辩护,他的前端JS代码非常棒,并且从静态分析工具中获得了非常可靠的分数)。我目前遇到的问题与项目中helper的类耦合有关。这是当前的实现:

...
Type iaccounthelpertype = typeof(IAccountsHelper), igettabletype = typeof(IGettable);
List<Tuple<IAccountsHelper, IGettable>> valid = new List<Tuple<IAccountsHelper, IGettable>>();
// Get all the types that implement IAccountsHelper and IGettable
IEnumerable<Type> types = AppDomain.CurrentDomain.GetAssemblies()
    .SelectMany(s => s.GetTypes())
    .Where(p => iaccounthelpertype.IsAssignableFrom(p) && igettabletype.IsAssignableFrom(p))
    .Select(x => x);
foreach (Type type in types)
{
    MethodInfo methodInfo = type.GetMethod("Get");
    try
    {
        methodInfo = methodInfo.MakeGenericMethod(typeof(T));
        IAccountsHelper helper = methodInfo.Invoke(null, null) as IAccountsHelper;
        valid.Add(Tuple.Create<IAccountsHelper, IGettable>(helper, helper as IGettable));
    }
    catch (NullReferenceException nullref)
    {
        // this is bad. The new object does not implement the proper static method. So we will carry this exception through.
        throw new Exception(type.Name + " does not implement the static generic method Get");
    }
    catch (ArgumentException e)
    {
        continue;
    }
}
...

这段代码允许以下实现(上面的函数名为Get)

IAccountsHelper helper = TheParentClass<UserPrincipal>.Get();

所以现在任何使用"helper"对象的代码都可以期望类执行的任何操作都是UserPrincipal类型的(就像创建用户的ActiveDirectory helper)。到目前为止,对于任何需要helper的代码单元,它都有一个更好的实现,而且没有更高的耦合率,从而增加了内聚性。它只是调用这个类,告诉它应该操作什么类型的对象,这个函数会把它映射到合适的类。我这样做是因为我无法找到一种方法来处理MVC/web api项目中的依赖注入。但是我觉得这些代码很脏,我认为它们可能是实现我正在做的事情的更好的方法。有没有人有任何建议,我可以,或者如果这段代码不脏,等等?

作为一个注释,我使用visual studio代码度量窗口来获得项目的类耦合,它从436减少到401,有5909行代码。(我发现你需要这两个有一个很好的凝聚力估计)。

asp.net mvc中的依赖注入模型

. NET MVC实际上对依赖注入框架有很好的支持。其中最受欢迎的是Ninject。如果你使用NuGet包管理器将Ninject MVC 5包引入到你的web项目中,它会自己完成大部分的设置魔法。然后你只需要在它的设置区域添加一个绑定:

Bind<IAccountsHelper>().To<UserPrincipal>();

然后使用构造函数注入在任何需要这些的类中:

public MyController(IAccountsHelper accountsHelper)
{
    _accountsHelper = accountsHelper;
}