I'm trying to get an example of EF 7 with Azure Table Storage to work in VS 14 CTP3, but I am having no luck with the dependency injection stuff. I was able to get an example with SQL done fairly easily, but I am seeing an issue that doesn't make sense: The referenced package is there and being pulled in, and if I look at it, it contains the correct namespaces, methods, clases etc., but the compile doesn't like it.
Here is my project.json:
{
"dependencies": {
"Microsoft.AspNet.Server.IIS": "1.0.0-alpha3",
"EntityFramework.AzureTableStorage": "7.0.0-alpha3",
"Microsoft.AspNet.RequestContainer": "1.0.0-alpha3"
},
"frameworks" : {
"net451" : { },
"k10" : { }
}
}
using System;
using Microsoft.AspNet.Builder;
using Microsoft.Data.Entity; /* <- 'missing reference' unless I add EntityFramework to project.json */
using Microsoft.Data.Entity.AzureTableStorage; /* <- ALWAYS errors w/ 'missing reference' */
using Microsoft.Framework.DependencyInjection;
namespace WebApplication2
{
public class Startup
{
public void Configure(IBuilder app)
{
app.UseServices(services =>
{
services.AddEntityFramework() /* <-- this errors too */
.AddAzureTableStorage();
services.SetupOptions<DbContextOptions> //,- says it can't find this
(config => config.UseAzureTableStorage("UseDevelopmentStorage=true"));
});
}
}
}
The strange thing is, if I right click and 'go to definition' on any of the 'missing' classes or methods, it brings them up, and I can see that I'm using them as defined. Am I missing something terribly obvious? Or is this stuff just not fully cooked yet?
Your project.json has both frameworks mentioned so VS builds both of them. If your intention is to just build for net451, you should remove the following from your project.json -
"k10" : { }
Related
The problem:
The dotnet ef Migrations add MyNewMigration command fails with:
No database provider has been configured for this DbContext. A
provider can be configured by overriding the DbContext.OnConfiguring
method or by using AddDbContext on the application service provider.
If AddDbContext is used, then also ensure that your DbContext type
accepts a DbContextOptions object in its constructor and
passes it to the base constructor for DbContext.
There are many SO posts regarding this issue, and I have read most of them. The one that seems to have the exact same problem is here:
EF Core unable to run commands. Error: No database provider has been configured for this DbContext
However, the issue was never resolved. Here are some bullets that sums the investigation up and further down, details about the steps.
We had initially just hardcoded the connection string in the DbContext OnConfiguring method, and then the Migrations command worked well.
We then proceeded to use a static method, that read the appsettings.json file. This worked when running the app, but it did not work when running the Migrations add command, because the connectionString we fetched from the static class, always returned null.
We then moved to use dependency injection, like everyone everywhere suggests doing. in the Startup.cs, we use something like services.AddDbContext<MyDbContext> and in the MyDbContext we have a constructor like public MyDbContext(DbContextOptions<MyDbContext> options) : base(options). The constructor is called, the connectionstring is there, app can run, but Migrations Add fails with same error message as above.
I then tested removing the default empty constructor, just keeping the MyDbContext(DbContextOptions<MyDbContext> options) constructor. The error message from the command was then "Unable to create an object of type 'MyDbContext'."
Since I run the commands from my Data project (where entities, dbcontext etc exists), I tried adding a startup path to the command, like dotnet ef Migrations add MyMigrationStuff --startup-project C:\Git\MyProject\MyProject.Api, still without default/empty constructor. This time, the error message was simply Build failed. I then reinstated the empty construtor, ran same command again: then I get the same error as above.
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
// ... other stuff
string cString = configuration["ConnectionStrings:MyDb"]; // cString is correct and valid!
services.AddDbContext<MyDbContext>(options => options.UseMySql(cString, mySqlOptions => mySqlOptions
.ServerVersion(new ServerVersion(new Version(5, 0, 17), ServerType.MySql))));
// services.AddDbContext<MyDbContext>(); // without DI as in case 1 and 2 above
}
cString looks correct when running app:
MyDbContext:
public class MyDbContext : DbContext
{
// DbSet etc...
public MyDbContext() : base()
{
}
public MyDbContext(DbContextOptions<MyDbContext> options) : base(options)
{
// If I break here, the options has two Extensions, looks ok, see below.
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
}
}
This is the options in the MyDbConstructor:
appsettings.json
{
"Logging": {
"IncludeScopes": false,
"Debug": {
"LogLevel": {
"Default": "Warning"
}
},
"Console": {
"LogLevel": {
"Default": "Warning"
}
}
},
"ConnectionStrings": {
"MyDb": "Server=localhost;Port=3308;Database=mydb;User=root;Password=root;"
}
}
I am running ASP.NET Core 3.1.101, EF Core 3.1.1, visual studio 2019.
you need to install MySQL provider using this cmd:
dotnet add package MySql.Data.EntityFrameworkCore
then add this code to your DBContext class constructor:
protected override void OnConfiguring(DbContextOptionsBuilder options)
{
options.UseMySQL(Configuration.GetConnectionString("MyDb"));
}
finally, add this line into your startup.cs class instead of what you did put:
services.AddDbContext<MyDbContext>();
besides the normal appsettings.config file, I have an additional one, which looks like this:
{
...
"region": "eu",
...
}
I'm trying to figure out how to register them to be available with IOptions injection - the main issue here is that, those settings cannot be placed within a section (don't ask why), like
{
...
"mySection": {
"region": "eu",
}
...
}
and in that case I cannot register the strongly-typed POCO configuration:
services.Configure<mySettings>(Configuration.GetSection("mySection"));
do you know how to fix it ?
Use the action overload of Configure<T>:
services.Configure<mySettings>(c => {
c.Region = Configuration["region"]
// etc.
});
I am trying to create a strongly typed config section but struggling. Examples show that I can have a POCO and simply have an entry in my json this should automatically resolve.
This is what I have in ConfigureServices(). Please note, the configuration is IConfigurationRoot:
public void ConfigureServices(IServiceCollection services)
{
services
.AddOptions()
.AddMvcCore()
.AddJsonFormatters();
services.Configure<MySettings>(this.configuration.GetSection("MySettings"));
}
This is my POCO
public class MySettings
{
public string Foo { get; set; }
}
I get a compiler error Error:(41, 44) : Argument 2: cannot convert from 'Microsoft.Extensions.Configuration.IConfigurationSection' to 'System.Action<MySettings>'.
The JSON config:
{
"MySettings": {
"Foo": "hello world"
}
}
Clearly, I am doing something silly but unsure what this could be. All sources on the web suggest this "should" work.
If further info is required then I can provide that.
You are missing
"Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0"
in your project.json file.
(The version may be different in your specific case)
A more complete answer is that you need to add the following nuget package to your ASP Core Project if you want to configure the strongly typed config in that way.
Microsoft.Extensions.Options.ConfigurationExtensions
The extension methods contained in the package will allow you to configure the strongly typed configuration the way you want to and the way most tutorials show.
services.Configure<MyOptions>(Configuration);
Alternatively, you could add another binder package:
Microsoft.Extensions.Configuration.Binder
Configuration would then look something like this:
services.AddOptions();
services.Configure<MyOptions>(x => Configuration.Bind(x));
This is the downside of having so many modular packaged up extensions. It gets easy to lose track of where functionality exists.
I've jumped many hurdles, but alas I still see the default 404 iamge rendered by Nancy.
I've 'mastered' project.json so I can embed my assets (including /assets/views/index.html), using the following block in the project.json file:
"buildOptions": {
"embed": [
"assets/**",
"Content/**",
"fonts/**",
"Scripts/bootstrap.js",
"Scripts/jquery-2.2.2.js",
"Scripts/mustache.js",
"favicon.ico"
//, "Scripts/**" - include this and build fails with errors in *.targets (!)
]
}
This is confirmed when debugging and querying assembly resources. All good.
My Bootstapper contains:
protected override void ConfigureApplicationContainer(TinyIoCContainer container)
{
DependencyResolver.ConfigureDependencies(container);
ResourceViewLocationProvider
.RootNamespaces
.Add(GetAssembly(), "<name to assembly>"); //embedded resource directory location
}
And yet in my IndexModule:
public class IndexModule : NancyModule
{
public IndexModule()
{
Get("/", args => Response.AsFile("assets/views/index.html", "text/html"));
}
}
This renders nothing... could I be missing anything ? It was working fine with .Net Framework
I'm in the process of converting an ASP.NET MVC3 (LinqToSQL, EntityFramework) project to MVC4. I've created a fresh MVC4 project in VS2012, added packages, copied my Views, Controllers, etc.
Most things seem to work fine except when I try to access a controller that makes use of a Respository, as follows:
public class CustomerController : Controller
{
private ICustomerRepository _cr;
public CustomerController()
{
this._cr = new CustomerRepository(TTDataProvider.DB);
}
public CustomerController(ICustomerRepository customerRepository)
{
this._cr = customerRepository;
}
if I'm in VS2012 and debugging, what I'll get is an exception: "Activation error occured while trying to get instance of type CustomerController, key """. The exception is of type Microsoft.Practices.ServiceLocation.Activation and the Inner Exception is: "StructureMap Exception Code: 202\nNo Default Instance defined for PluginFamily TTLW.Models.TTLWDataContext, TTLW, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"}.
My IoC code is:
using StructureMap;
using FluentSecurity;
using System.Diagnostics;
namespace TTLW {
public static class IoC {
public static IContainer Initialize() {
ObjectFactory.Initialize(x =>
{
x.Scan(scan =>
{
scan.TheCallingAssembly();
scan.WithDefaultConventions();
scan.AddAllTypesOf<IPolicyViolationHandler>();
});
});
return ObjectFactory.Container;
}
}
}
And here's StructureMapMVC.cs
using System.Web.Http;
using System.Web.Mvc;
using StructureMap;
using TTLW.DependencyResolution;
[assembly: WebActivator.PreApplicationStartMethod(typeof(TTLW.App_Start.StructuremapMvc), "Start")]
namespace TTLW.App_Start {
public static class StructuremapMvc {
public static void Start() {
IContainer container = IoC.Initialize();
DependencyResolver.SetResolver(new StructureMapDependencyResolver(container));
GlobalConfiguration.Configuration.DependencyResolver = DependencyResolver.Current.ToServiceResolver();
}
}
}
As I say, this was all working without problems in my MVC3 application (although I was of course using the MVC3 version of StructureMap).
Once I hit the exception, if I just choose to continue then everything works (i.e. the controller functions); this is confirmed by choosing "Start Without Debugging" instead of "Debug". When I do that there is no exception thrown and things work as designed.
I've searched and come across posts from Phil Haack, Brett Allred and others (in fact I've already incorporated Allred's code in the last line of StructureMapMVC) but haven't found a solution. I can't consider the project converted as long as this exception is staring me in the face.
I've included all the code and messages I think are reasonable and would appreciate any insights. If you need to see more just let me know.
Thanks in advance.