【问题标题】:Can I use Dependency Injection in a ViewModel for DbContext? Core2.0我可以在 DbContext 的 ViewModel 中使用依赖注入吗?核心2.0
【发布时间】:2018-01-28 06:24:42
【问题描述】:

我正在尝试将应用程序从框架项目迁移到 Core 2.0。我遇到的问题与this one 非常相似,但我正在尝试使用 DI。我根据该问题创建了一个示例项目,但使用的视图模型类似于我在项目中使用它的方式。我一直在试图找出我在一天多的时间里做错了什么,所以希望这里有人可以提供帮助。

In case It's helpful code on github

在做了一些研究之后,我根据这篇文章中的 cmets 更改了我的应用程序使用我的视图模型的方式,并开始使用存储库模式。我更新了 git hub 示例以反映我的更改,以防它对任何人有所帮助。

ApplicationDbContext.cs

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public DbSet<Gig> Gigs { get; set; }
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
        : base(options)
    {
    }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);
        // Customize the ASP.NET Identity model and override the defaults if needed.
        // For example, you can rename the ASP.NET Identity table names and more.
        // Add your customizations after calling base.OnModelCreating(builder);
    }

    public DbSet<gigs2.Models.Gig> Gig { get; set; }
}

GigsController.cs

public class GigsController : Controller
{
    // GET: Gigs
    public ActionResult Index()
    {
        GigsViewModel vm = new GigsViewModel();
        vm.Get();
        return View(vm);
    }
}

我在new GigsViewModel(); 上出错了,因为我需要将选项传递给 ApplicationDbContext

没有给出与所需形式相对应的参数 参数“选项”的 'ApplicationDbContext.ApplicationDbContext(DbContextOptions)'

GigsViewModels.cs

 public class GigsViewModel
{
    private ApplicationDbContext _context;

    public GigsViewModel(ApplicationDbContext context) {
        _context = context;

    }
    public List<GigViewModel> Gigs { get; set; }

    public void Get()
    {
        Gigs = _context.Gigs.Select(g => new GigViewModel {
            Id = g.Id,
            Date = g.Date,
            Time = g.Time,
            Venue = g.Venue
        }).ToList();
    }
}

startup.cs

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

        services.AddIdentity<ApplicationUser, IdentityRole>(options =>
        {
            options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!#$%&'*+-/=?^_`{|}~.@ ";
            options.User.RequireUniqueEmail = false;
            options.Password.RequireDigit = false;
            options.Password.RequiredLength = 4;
            options.Password.RequireDigit = false;
            options.Password.RequireNonAlphanumeric = false;
            options.Password.RequireUppercase = false;
            options.Password.RequireLowercase = false;
        })
            .AddEntityFrameworkStores<ApplicationDbContext>()
            .AddDefaultTokenProviders();
        services.AddScoped<UserManager<ApplicationUser>, ApplicationUserManager>();
        services.AddScoped<SignInManager<ApplicationUser>, ApplicationSignInManager<ApplicationUser>>();
        services.Configure<Configuration.cofAuthSettings>(Configuration.GetSection("cofAuthSettings"));


        // Add application services.
        services.AddTransient<IEmailSender, EmailSender>();

        services.AddMvc();
    }

【问题讨论】:

  • 当您要求它在数据库中查找自己时,我认为您的 GigsViewModel 不再是 view model。在任何情况下,GigsViewModel 只是一个类,是的,您可以使用 DI 容器注入依赖项。但是您自己newing 类,而不是向 DI 容器请求实例。但这没有实际意义——只需自己实例化并返回模型。您不需要 DI 容器来为您的视图模型类提供实例。

标签: c# mvvm dependency-injection asp.net-core asp.net-core-2.0


【解决方案1】:

向您的GigsController 类添加一个构造函数,该类接受您的GigsViewModel 实例。这将允许 IoC 容器构建依赖关系树(而不是像现在这样自己创建它。

这样的事情应该可以工作:

private readonly GigsViewModel _gigsViewModel;

public GigsController(GigsViewModel gigsViewModel)
{
    _gigsViewModel = gigsViewModel;
}

// GET: Gigs
public ActionResult Index()
{
    _gigsViewModel.Get();
    return View(_gigsViewModel);
}

【讨论】:

  • 嗯,这让我过去了,但是当我测试时,我现在收到此错误“”InvalidOperationException:尝试激活“gigs2”时无法解析类型“gigs2.Models.GigsViewModels.GigsViewModel”的服务。 Controllers.GigsController'。”我认为可能是相关的。
  • 那是因为你还没有在 IoC 容器中注册GigsViewModel(在你的startup.cs 中)。要解决此问题,请在 ConfigureServices 方法的某处添加以下行:services.AddScoped&lt;GigsViewModel&gt;(); 请注意,您必须为所有希望 IoC 容器解析的视图模型类执行此操作(您的控制器由框架自动添加)。
  • 感谢您的反馈,在进行了更多研究之后,由于您的 cmets,我希望对应用程序进行更多更新,以使用比以前更好的做法。
  • 这在技术上是正确的,但仍然是一个糟糕的设计。将 DbContect 注入控制器,然后使用适当的转换工具构建 ViewModel。 Get() 应该去。
猜你喜欢
  • 2016-11-08
  • 1970-01-01
  • 2018-12-14
  • 2020-04-04
  • 1970-01-01
  • 2018-05-06
  • 2018-01-03
  • 1970-01-01
  • 2019-02-16
相关资源
最近更新 更多