repository pattern on asp core - asp.net

we are trying to develop a asp core application (MVC) using ef code first . however it seems that requires the db context to be in an executable and not class library .
so the data context was added in the web UI project but the issue that how can the db context's dbset be made available in the repository project ..
example code is as under:
public class CompanyRepository : GenericRepository<Company>, /*IGenericRepository<Company>*/ ICompanyRepository
{
public CompanyRepository(DbContext dbContext) : base(dbContext)
{
}
public async Task<IEnumerable<Company>> GetAllAsync()
{
return await base.GetAllAsync<Company>();
}
}
MVC Project StartUp .cs
services.AddDbContext<DBContext>();
services.AddScoped<ICompanyRepository, CompanyRepository>();
DBCOntext.cs in MVC Project
public class DBContext : DbContext
{
private IConfigurationRoot _config;
public DBContext(IConfigurationRoot config, DbContextOptions options):base(options)
{
_config = config;
}
}
currently it seems to raise following error:
An unhandled exception occurred while processing the request. InvalidOperationException: Unable to resolve
service for type 'Microsoft.EntityFrameworkCore.DbContext' while
attempting to activate
'On.Store.Repository.Companies.CompanyRepository'.

We have two problems here:
1) When you configure services in a Startup class, you are configuring your custom context (for easier reference, let's name it CustomDbContext):
public class CustomDbContext: DbContext
{
... and in the Startup class:
services.AddDbContext<CustomDbContext>();
... so in your repository, you need to inject a context of declared class, instead of base DbContext class:
// THIS WILL NOT WORK
public class CompanyRepository : GenericRepository<Company>, ICompanyRepository
{
public CompanyRepository(DbContext dbContext) : base(dbContext)
{
}
}
// THIS WILL WORK
public class CompanyRepository : GenericRepository<Company>, ICompanyRepository
{
public CompanyRepository(CustomDbContext dbContext) : base(dbContext)
{
}
}
2) Problem number two is revealed directly from the first problem. So you have CustomDbContext declared in a MVC project, so cannot be used in a referenced repository project. So the solution seems to be easy, you need to move the CustomDbContext out of the MVC project (either to repository project or any other/third project which could be referenced by both MVC and repository). In such way you will easy configure your CustomDbContext in a Startup class, as well as use this context in repositories.
3) As it comes to registering context from external library you can do it easily with MigrationsAssembly method, it will look like this:
services.AddDbContext<CustomDbContext>(options => options.UseSqlServer(
_configuration.GetConnectionString("YourConnectionStringName"),
b => b.MigrationsAssembly("YourExternalAssemblyName")));

This is an very simples project that can help you and other developers.
Generic Repository Pattern in ASP.NET Core

This is addressing your orginal issue of being unable to use migration command line tools and allow you to keep proper separation of layers.
This is a know issue (tracked here) and there are two workarounds as of now, directly taken from the EntityFramework Core documentation:
Workaround 1 - Utilize a separate startup project
Convert the class library project into an “app” project. This can either be a .NET Core app or a desktop .NET app.
Example:
{
"frameworks": {
"netcoreapp1.0": {
"dependencies": {
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.0.0-*"
}
}
}
}
}
Be sure to register the EntityFramework Tools as a project dependency and in the tools section of your project.json.
Example:
{
"dependencies": {
"Microsoft.EntityFrameworkCore.Tools": {
"version": "1.0.0-preview2-final",
"type": "build"
}
},
"tools": {
"Microsoft.EntityFrameworkCore.Tools": "1.0.0-preview2-final"
}
}
Finally, specify a startup project that is a “runnable app.”
Example:
dotnet ef --startup-project ../MyConsoleApplication/ migrations list
Workaround 2 - Modify your class library to be a startup application
Convert the class library project into an “app” project. This can either be a .NET Core app or a desktop .NET app.
To make the project a .NET Core App, add the “netcoreapp1.0” framework to project.json along with the other settings in the sample below:
{
"buildOptions": {
"emitEntryPoint": true
},
"frameworks": {
"netcoreapp1.0": {
"dependencies": {
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.0.0-*"
}
}
}
}
}
To make a desktop .NET app, ensure you project targets “net451” or newer (example “net461” also works) and ensure the build option "emitEntryPoint" is set to true.
{
"buildOptions": {
"emitEntryPoint": true
},
"frameworks": {
"net451": { }
}
}

Related

Properties Added with Aspects Not in Generated JSON Schema

I'm trying to generate JSON Schemas using Newtonsoft JSON Schema. Regular properties added in my POCO class are added to the schema when it is generated. I'm also using PostSharp Aspects to add properties, but none of those are added to the schema.
This is a Console application targeting .NET 4.7.2.
Here is my Console application:
public class Program
{
private static void Main(string[] args)
{
JSchemaGenerator gen = new JSchemaGenerator();
JSchema schema = gen.Generate(typeof(MyClass));
File.WriteAllText("C:\\Temp\\TestSchema.json", schema.ToString());
}
}
Here is my aspect:
[PSerializable]
public class TestAspect : InstanceLevelAspect
{
[IntroduceMember]
[JsonProperty(Required = Required.Always)]
public string AspectProp { get; set; }
}
And here is my POCO:
[TestAspect]
public class MyClass
{
public int MyProperty { get; set; }
}
Finally, here is the generated schema:
{
"type": "object",
"properties": {
"MyProperty": {
"type": "integer"
}
},
"required": [
"MyProperty"
]
}
The MyProperty property is in the schema, but AspectProp - the property added by the aspect - is not.
When I open the exe in a decompiler, I can see that AspectProp is actually added to MyClass:
I'm not sure if this is a problem with PostSharp or Newtonsoft JSON Schema or if I'm doing something wrong. It seems like this should be possible.
Edit 1: 20 May
I split my solution out into separate projects - one for the Console app, one for the Aspect and one for MyClass. After making sure I was referencing the generated MyClass DLL directly (i.e. not a project reference, I actually removed the project once MyClass was built) it did not make a difference. AspectProp is still not in the schema. Based on this and the serialization suggested below by #dbc, this leads me to believe it is a problem with the Newtonsoft schema generator
Edit 2: 20 May
Per Antonin's Answer below, I created a new ContractResolver:
public class AspectPropertyResolver : DefaultContractResolver
{
public AspectPropertyResolver()
{
SerializeCompilerGeneratedMembers = true;
}
}
And then registered it in my app before calling Generate:
gen.ContractResolver = new AspectPropertyResolver();
Now my schema includes the aspect-generated property.
Newtonsoft.Json has an opt-in feature to serialize compiler-generated properties. See Newtonsoft.Json.Serialization.DefaultContractResolver.SerializeCompilerGeneratedMembers property.

ASP.NET Core RC2 Configure Custom AppSettings

Say I put the settings below in appsettings.json.
"MySettings": {
"SmtpHost": "smtp.mydomain.com"",
"WebService": "http://localhost:1337"
}
And I have the class below to hold those settings.
public class MySettings
{
public string SmtpHost{ get; set; }
public string WebService{ get; set; }
}
With RC1 I would use the line of code below in the ConfigureServices() method to load those configuration settings.
services.Configure<MySettings>(Configuration.GetSection("MySettings"));
But in RC2 that same line of code gives me this error
Cannot convert from
'MicrosoftExtensions.Configuration.IConfigurationSection' to
'System.Action<MySettings>'.
You simply need to reference a different package with RC2. In your project.json simply add a reference to the "Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0-rc2-final" package, and you'll get the correct extension method that you're looking for.
"dependencies": {
"Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0-rc2-final"
}
Like several of the changes with ASP.NET Core RC2, there was a lot of re-packing and moving of things. I put together a migration guide that you might find useful.
you need to add the package:
"Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0-rc2-final",
and make sure you have this using:
using Microsoft.Extensions.Configuration;

Location of IWebProxy implementation for .NET Core

What is the available implementation of the System.Net.IWebProxy (from System.Net.Primitives, DNX Core)? By application requirement, the only framework can be used in dnxcore50, so what is the right NuGet package that contains proxy implementations?
What is the correct way to resolve such questions? Related functionality seems to be split among dozen of packages.
Despite the name, IWebProxy implementation does not actually need to implement any proxying, it just provides information about the proxy. So, you can create your own implementation:
public class MyProxy : IWebProxy
{
public Uri GetProxy(Uri destination)
{
return new Uri("http://localhost:8888");
}
public bool IsBypassed(Uri host)
{
return false;
}
public ICredentials Credentials { get; set; }
}
There is a WebProxy class in the System.Net namespace (source here) that you can use.
Make sure your project.json file has these two lines under "dependencies"
"frameworks": {
"dotnet5.4": {
"dependencies": {
"Microsoft.Net.Http": "2.2.29",
"System.Net.Primitives": "4.0.11-beta-23516"
}
}
}

CGI errors when hosting on Azure

I have a website that runs fine on my local IISExpress but when I upload it to Azure it is tediously slow and often returns an error: The specified CGI application encountered an error and the server terminated the process
In project.json I have (amongst others) these dependencies:
"Microsoft.AspNet.IISPlatformHandler": "1.0.0-*",
"Microsoft.AspNet.Server.Kestrel": "1.0.0-*",
"Microsoft.AspNet.Hosting": "1.0.0-*",
and these commands:
"commands": {
"web": "MyApp",
},
My hosting.json file has:
{
"server": "Microsoft.AspNet.Server.Kestrel"
}
And my Startup.cs has:
public class Startup
{
public IConfigurationRoot Configuration { get; set; }
public static void Main(string[] args)
{
var application = new WebApplicationBuilder()
.UseConfiguration(WebApplicationConfiguration.GetDefault(args))
.UseStartup<Startup>()
.Build();
application.Run();
}
//etc...
Should I be using Kestrel or not? I'm not targeting any non-Windows platforms so it's just IISExpress and Azure I'm interested in.
I had to upgrade from the free/shared to a B1 instance. Apparently the packages during deployment are too big for the free/shared setups.

How do I add a Web API component to my MVC 6 app?

I have a newly created MVC 6 app, based on the ASP.NET 5 Web Application template, and I would like to include some Web API functionality in this project. It's easy to add an API/Controllers folder, and add [api] controllers there, but I cannot configure Web API, When I try and add the following code:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
I get a compile error that HttpConfiguration is an unknown type. I have tried adding references to web API ( I can't recall which), but showed as errors in my references folder.
Too big to comment, so putting it here:
If you create MVC6 application, you can just inherit your Api controller from Microsoft.AspNet.Mvc.Controller and no need for System.Web.Http.ApiController since mvc and webapi are getting under one roof.
You can check more in Migrate Models and Controllers section
Getting started: WebApi in MVC6
Edit
You can try following steps to resolve System.Web.Http.HttpConfiguration
1) Add reference to following dependency in project.json file (you can add as Nuget package also)
"dependencies": {
...
...
"Microsoft.AspNet.WebApi": "5.2.3"
},
2) Add reference to System.Web from framework assemblies section
That should do following change in "project.json" otherwise do it manually
"frameworks": {
"dnx451": {
"frameworkAssemblies": { //This section will be added
"System.Web": "4.0.0.0" //This reference will be added
}
}
3) Remove dnxcore50 under frameworks section in project.json, since System.Web itself not available in DNX Core 5.0. It is shown in intellisense also.
"frameworks": {
"dnx451": {
"frameworkAssemblies": {
"System.Web": "4.0.0.0"
}
},
"dnxcore50": { } //Remove this node. Remove comma(,) in above line too!!
},
4) Clean and Rebuild solution. Hopefully that should resolve the references.
I have followed these steps in a new MVC 6 application and was able to instantiate HttpConfiguration properly just for test inside a controller.
Note: I didn't verified the functionality of the instance and so can't guaranty the functionality since its not in support!!
Hope this help you...

Resources