简体   繁体   English

.NET MVC 5 分成不同的项目:避免循环引用

[英].NET MVC 5 separate into different projects: avoid circular reference

I have a solution that contains just one single project ( MVC 5 with Identity and EF ).我有一个只包含一个项目的解决方案(带有IdentityEFMVC 5 )。 The db context is an ApplicationDbContext (a subclass of IdentityDbContext which is itself a subclass of EF DbContext). db 上下文是ApplicationDbContext (IdentityDbContext 的子类,它本身是 EF DbContext 的子类)。 I also have a custom validation attribute that needs to use the db context to do its thing:我还有一个自定义验证属性,需要使用 db 上下文来做它的事情:

public class RequiredIfRol : ValidationAttribute, IClientValidatable {
    //...
    protected override ValidationResult IsValid(object value, ValidationContext validationContext) {
        // ...
        string nomRol = "";
        //instance and use the ApplicationDbContext
        using (ApplicationDbContext db = new ApplicationDbContext()) {
            var roldb = db.Roles.Find(rolId);
            if (roldb == null) return ValidationResult.Success;
            nomRol = db.Roles.Find(rolId).Name;
        }
        // more code here
    }
}

This is working ok.这工作正常。

Now, after reading about it, I am trying to separate this MVC project into several projects:现在,在阅读了它之后,我试图将这个 MVC 项目分成几个项目:

  • a class library for the DAL (it will contain the EF models and the ApplicationDbContext), DAL的 class 库(它将包含 EF 模型和 ApplicationDbContext),
  • another one for the business logic,另一个用于业务逻辑,
  • another one with common things另一个有共同点
  • and then the MVC project.然后是MVC项目。

I am noob on this, since I have always had everything inside the same MVC project, so I am confused: I think the attribute should reside in the Common project, so that it can be referenced from the DAL (to decorate models) and also from the MVC (to decorate viewmodels).我对此很陌生,因为我总是在同一个 MVC 项目中拥有所有东西,所以我很困惑:我认为该属性应该驻留在 Common 项目中,以便可以从 DAL 中引用它(以装饰模型)并且来自 MVC(用于装饰视图模型)。

Since the Common project will be referenced from all the other projects, I guess I can not reference any of those projects from the Common (circular reference?).由于 Common 项目将从所有其他项目中引用,我想我不能从 Common 中引用任何这些项目(循环引用?)。 and, as the ApplicationDbContext (which the attribute needs to use) will reside in the DAL project, I have a problem here...并且,由于 ApplicationDbContext (属性需要使用)将驻留在 DAL 项目中,我这里有一个问题......

I am pretty sure I am designing this badly, but cant find a correct way to do it.. Any help?我很确定我设计得很糟糕,但找不到正确的方法来做到这一点..有什么帮助吗?


ADDED:添加:

this is something I had tried:这是我尝试过的:

1.- in the common library, defined an interface: 1.-在通用库中,定义了一个接口:

public interface IMyInterface {
    System.Data.Entity.IDbSet<CustomRole> Roles { get; set; }
}

2.- in the applicationDbContext, modified its declaration so that it implements the interface: 2.- 在 applicationDbContext 中,修改其声明,使其实现接口:

public class ApplicationDbContext : IdentityDbContext<ApplicationUser, CustomRole, int, CustomUserLogin, CustomUserRole, CustomUserClaim>, IMyInterface {...}

3.- then in the attribute, try to get an implementation of the interface by adding an getter property: 3.-然后在属性中,尝试通过添加getter属性来获取接口的实现:

private IMyInterface _dbcontext { get { return DependencyResolver.Current.GetService<IMyInterface>(); } }

and then in the IsValid() method:然后在 IsValid() 方法中:

    var roldb = _dbcontext.Roles.Find(rolId);
    if (roldb == null) return ValidationResult.Success;
    nomRol = _dbcontext.Roles.Find(rolId).Name;

but this did not work...但这没有用......

One way around it would be to create an abstraction for your code using context - IRoleFinder and put in the common project alongside with your RequiredIfRol .一种解决方法是使用 context - IRoleFinder为您的代码创建一个抽象,并将其与您的RequiredIfRol一起放入公共项目中。 Then implement it in business logic layer and inject it in the MVC project.然后在业务逻辑层实现, 注入到MVC项目中。 This way you should be able to decouple you attribute from context.这样,您应该能够将属性与上下文分离。

ValidationAttribute.IsValid() has a ValidationContext parameter which you can use to resolve the dependency via ValidationContext.GetService method. ValidationAttribute.IsValid()有一个ValidationContext参数,您可以使用该参数通过ValidationContext.GetService方法解决依赖关系。

UPD UPD

Per your request in comment:根据您在评论中的要求:

For simplification, lets say I have only 2 projects (the class library with the attribute, and the MVC project with everything else).为简化起见,假设我只有 2 个项目(具有属性的 class 库,以及具有其他所有内容的 MVC 项目)。

In library you will have something like this:在图书馆里,你会有这样的东西:

interface IRoleFinder
{
    CustomRole Find(int id);
}
public class RequiredIfRol : ValidationAttribute, IClientValidatable {
    //...
    protected override ValidationResult IsValid(object value, ValidationContext validationContext) {
       // ...
       var roleFinder = (IRoleFinder) validationContext.GetService(typeof(IRoleFinder));
    }
}

In your MVC project:在您的 MVC 项目中:

public class RoleFinder : IRoleFinder
{
    public CustomRole Find(int id)
    {
        // use context here
    }
}

And in Startup (this is for ASP.NET Core, for MVC 5 you should find another way):在启动中(这是针对 ASP.NET 内核,对于 MVC 5,您应该找到另一种方法):

   services.AddTransient<IRoleFinder, RoleFinder>()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM