MvxException:无法从定位器为类型 x 初始化 ViewModel
MvxException: Failed to initialize ViewModel for type x from locator
拜访 Xamarin 和 MvvmCross 专家。我已经尝试调试此错误数小时 MvvmCross.Exceptions.MvxException: Failed to construct and initialize ViewModel for type TestApp.Core.ViewModels.IngredientsViewModel from locator MvxDefaultViewModelLocator
。我找到了导致此错误的代码片段,它与使用 EFCore sqlite 从数据库中提取数据有关。
这是我第一次将它用于移动应用程序,因此您可能会发现一些我看不到的东西。以下是我认为足够的所有信息,如果需要更多信息,请告诉我!我希望该解决方案可以帮助其他人。
请注意,当我注释掉GetIngredients
时,我没有得到上面的错误。
我的应用文件在Core/Shared项目
public class AppCore : MvxApplication
{
public override void Initialize()
{
Mvx.IoCProvider.RegisterType<TestContext>();
Mvx.IoCProvider.RegisterType<IIngredientRepository, IngredientRepository>();
RegisterAppStart<IngredientsViewModel>();
}
}
我的 DbContext
public class TestContext : DbContext
{
public TestContext() : base()
{
}
private const string _databaseName = "Test.db";
public DbSet<Ingredient> Ingredients { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
string databasePath;
switch (Device.RuntimePlatform)
{
case Device.iOS:
SQLitePCL.Batteries_V2.Init();
databasePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "..", "Library", _databaseName); ;
break;
case Device.Android:
databasePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), _databaseName);
break;
default:
throw new NotImplementedException("Platform not supported");
}
optionsBuilder.UseSqlite($"Filename={databasePath}");
}
}
存储库
public interface IRepository<TEntity> where TEntity : class
{
IEnumerable<TEntity> GetAll();
}
public class Repository<TEntity> : IRepository<TEntity> where TEntity : class
{
protected readonly TestContext Context;
public Repository(TestContext context)
{
Context = context;
}
public IEnumerable<TEntity> GetAll()
{
return Context.Set<TEntity>().ToList(); //after this line error is thrown
}
}
public interface IIngredientRepository : IRepository<Ingredient> {}
public class IngredientRepository : Repository<Ingredient>, IIngredientRepository
{
public IngredientRepository(TestContext testContext) : base(testContext)
{ }
}
我的视图模型
public class IngredientsViewModel : BaseViewModel
{
private IIngredientRepository IngredientRepository { get; set; }
public IngredientsViewModel(IIngredientRepository ingredientRepository)
{
IngredientRepository = ingredientRepository;
GetIngredients(); //when commented out, the view loads fine
}
private void GetIngredients()
{
var ingredients = IngredientRepository.GetAll();
Ingredients = new MvxObservableCollection<Ingredient>(ingredients);
}
private MvxObservableCollection<Ingredient> _ingredients;
public MvxObservableCollection<Ingredient> Ingredients
{
get => _ingredients;
set { SetProperty(ref _ingredients, value); }
}
}
在您的 TestContext.cs 中,尝试在构造函数中添加以下行:
Database.EnsureCreated(); //returns boolean which could be used for some check if needed
此外,我的建议是重写 OnModelCreating,例如:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
//creating tables according to UML
modelBuilder.Entity<Ingredient>();
//add one for each table
}
如果这没有帮助,请尝试检查 InnerException 或逐步调试。
拜访 Xamarin 和 MvvmCross 专家。我已经尝试调试此错误数小时 MvvmCross.Exceptions.MvxException: Failed to construct and initialize ViewModel for type TestApp.Core.ViewModels.IngredientsViewModel from locator MvxDefaultViewModelLocator
。我找到了导致此错误的代码片段,它与使用 EFCore sqlite 从数据库中提取数据有关。
这是我第一次将它用于移动应用程序,因此您可能会发现一些我看不到的东西。以下是我认为足够的所有信息,如果需要更多信息,请告诉我!我希望该解决方案可以帮助其他人。
请注意,当我注释掉GetIngredients
时,我没有得到上面的错误。
我的应用文件在Core/Shared项目
public class AppCore : MvxApplication
{
public override void Initialize()
{
Mvx.IoCProvider.RegisterType<TestContext>();
Mvx.IoCProvider.RegisterType<IIngredientRepository, IngredientRepository>();
RegisterAppStart<IngredientsViewModel>();
}
}
我的 DbContext
public class TestContext : DbContext
{
public TestContext() : base()
{
}
private const string _databaseName = "Test.db";
public DbSet<Ingredient> Ingredients { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
string databasePath;
switch (Device.RuntimePlatform)
{
case Device.iOS:
SQLitePCL.Batteries_V2.Init();
databasePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "..", "Library", _databaseName); ;
break;
case Device.Android:
databasePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), _databaseName);
break;
default:
throw new NotImplementedException("Platform not supported");
}
optionsBuilder.UseSqlite($"Filename={databasePath}");
}
}
存储库
public interface IRepository<TEntity> where TEntity : class
{
IEnumerable<TEntity> GetAll();
}
public class Repository<TEntity> : IRepository<TEntity> where TEntity : class
{
protected readonly TestContext Context;
public Repository(TestContext context)
{
Context = context;
}
public IEnumerable<TEntity> GetAll()
{
return Context.Set<TEntity>().ToList(); //after this line error is thrown
}
}
public interface IIngredientRepository : IRepository<Ingredient> {}
public class IngredientRepository : Repository<Ingredient>, IIngredientRepository
{
public IngredientRepository(TestContext testContext) : base(testContext)
{ }
}
我的视图模型
public class IngredientsViewModel : BaseViewModel
{
private IIngredientRepository IngredientRepository { get; set; }
public IngredientsViewModel(IIngredientRepository ingredientRepository)
{
IngredientRepository = ingredientRepository;
GetIngredients(); //when commented out, the view loads fine
}
private void GetIngredients()
{
var ingredients = IngredientRepository.GetAll();
Ingredients = new MvxObservableCollection<Ingredient>(ingredients);
}
private MvxObservableCollection<Ingredient> _ingredients;
public MvxObservableCollection<Ingredient> Ingredients
{
get => _ingredients;
set { SetProperty(ref _ingredients, value); }
}
}
在您的 TestContext.cs 中,尝试在构造函数中添加以下行:
Database.EnsureCreated(); //returns boolean which could be used for some check if needed
此外,我的建议是重写 OnModelCreating,例如:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
//creating tables according to UML
modelBuilder.Entity<Ingredient>();
//add one for each table
}
如果这没有帮助,请尝试检查 InnerException 或逐步调试。