Skip to content

Does this work with Core 3? I am not having much luck. #243

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
VictorioBerra opened this issue Oct 11, 2019 · 20 comments
Closed

Does this work with Core 3? I am not having much luck. #243

VictorioBerra opened this issue Oct 11, 2019 · 20 comments

Comments

@VictorioBerra
Copy link

My ServiceCollection never gets populated with any IRepositories. Before i start sharing code, im wondering does even work with the latest Core both EF Core and ASPNET Core?

@VictorioBerra
Copy link
Author

Some more info, apparently, in aspnet core 3 you can no longer return IServiceProvider from ConfigureServices. So you will need to somehow allow us to register in program.cs during the hostbuilder setup via useserviceproviderfactory

Also, until now, I did not know using StructureMap's IOC method forces you to use StructureMap as your IoC container. Am I understanding that correctly? That is not really an acceptible solution IMO... you should use the default core IoC implementation if possible.

@omarpiani
Copy link
Member

Hi, I try to setup in a .NET Core MVC project and effectivelly dependency resolution has some problems... in general there is no problem with .NET Standard 2.0 libraries, for instance this guy #242

Why I use structuremap even in .net core is explained here: #191

@omarpiani
Copy link
Member

omarpiani commented Oct 14, 2019

structuremap/StructureMap.Microsoft.DependencyInjection#47

You are ritght, we need to update something, probably is time to move to Lamar as suggested by StructureMap developers

@omarpiani
Copy link
Member

I updated some things in order to get working a ASP.NET Core 3.0 project.
I didn't found how to configure a new ASP.NET Core 3.0 configured with a single row.

This guide helps you to setup a project with Autofac

Let me know if works!

@VictorioBerra
Copy link
Author

VictorioBerra commented Oct 25, 2019

Did you do the work in a branch or is this just on master/develop?

@omarpiani
Copy link
Member

it's merged today in develop

@VictorioBerra
Copy link
Author

Version conflict detected for Microsoft.Extensions.DependencyInjection. Install/reference Microsoft.Extensions.DependencyInjection 3.0.0 directly to project MyApp to resolve this issue. 
 MyApp  -> Microsoft.EntityFrameworkCore.Sqlite 3.0.0 -> Microsoft.EntityFrameworkCore.Sqlite.Core 3.0.0 -> Microsoft.EntityFrameworkCore.Relational 3.0.0 -> Microsoft.EntityFrameworkCore 3.0.0 -> Microsoft.Extensions.DependencyInjection (>= 3.0.0) 
 MyApp  -> SharpRepository.Ioc.Microsoft.DependencyInjection 2.1.0-prerelease -> Microsoft.Extensions.DependencyInjection (>= 2.1.0 && < 3.0.0). 

image

@omarpiani
Copy link
Member

It's right, you dont need SharpRepository.Ioc.Microsoft.DependencyInjection, remove it

@VictorioBerra
Copy link
Author

So how do I register my config and all that without that package?

@VictorioBerra
Copy link
Author

Ohh you said to use AutoFac, I see.

@VictorioBerra
Copy link
Author

Can you elaborate on why we need this:

// Passes service provide to SharpRepository
RepositoryDependencyResolver.SetDependencyResolver(app.ApplicationServices);

@VictorioBerra
Copy link
Author

VictorioBerra commented Oct 25, 2019

ObjectDisposedException: Cannot access a disposed object. A common cause of this error is disposing a context that was resolved from dependency injection and then later trying to use the same context instance elsewhere in your application. This may occur if you are calling Dispose() on the context, or wrapping the context in a using statement. If you are using dependency injection, you should let the dependency injection container take care of disposing context instances.
Object name: 'ApplicationDbContext'.

Not sure what I am missing.

EDIT: This is probably my fault, this goes back to why I did not want to mess with the ASPNET Core DI container. Basically I was seeding data in my Program .CS like so:

public static async Task Main(string[] args)
{
    IHost webHost = CreateHostBuilder(args).Build();

    using var scope = webHost.Services.CreateScope();
    var identitySeed = scope.ServiceProvider.GetRequiredService<IdentitySeed>();
    var dataSeed = scope.ServiceProvider.GetRequiredService<DataSeed>();
    var context = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();

    context.Database.Migrate();

    await identitySeed.CreateRoles();

    var seed = args.Contains("/seed");
    if (seed)
    {
        await dataSeed.Seed();
    }

    await webHost.RunAsync();
}

If you want to seed data before your app host is started, apparently you will have to find another way... shouldnt the dbcontext be scoped? Not sure why disposing of it once prevents it from ever again being used. I do not use Autofac so I didn't want to have to learn a whole new thing.

EDIT 2: Fixed by wrapping my using in a new block.

EDIT 3: Not fixed...... my program only works ONCE. If I hit F5 it crashes with that disposed error.

@omarpiani
Copy link
Member

RepositoryDependencyResolver.SetDependencyResolver(app.ApplicationServices); because inside sharprepository I need to resolve DbContext or IMemoryCache or whatever

Seed in Main? are you using EntityFrameworkCore? https://docs.microsoft.com/it-it/ef/core/modeling/data-seeding here's how

@VictorioBerra
Copy link
Author

For the record I am using IdentityDbContext, so maybe that wont work???

@VictorioBerra
Copy link
Author

Heres my startup:

Right now, if I click F5 on my web page, my app crashed with "object disposed" exception on my public class ApplicationDbContext : IdentityDbContext

using System;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Pumpkin.Beer.Taste.Data;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using AutoMapper;
using Microsoft.AspNetCore.HttpOverrides;
using Pumpkin.Beer.Taste.Services;
using Autofac;
using SharpRepository.Ioc.Autofac;
using Pomelo.EntityFrameworkCore.MySql.Infrastructure;
using SharpRepository.Repository.Ioc;

namespace Pumpkin.Beer.Taste
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<ApplicationDbContext>(options => { 
                options.UseMySql(Configuration.GetConnectionString("MySQLConnection"), mySqlOptions =>
                {                    
                    mySqlOptions.ServerVersion(new Version(5, 7), ServerType.MySql); // replace with your Server Version and Type
                });
            });

            services
                .AddDefaultIdentity<IdentityUser>(options => {
                    options.Password.RequireDigit = false;
                    options.Password.RequiredLength = 4;
                    options.Password.RequireLowercase = false;
                    options.Password.RequireNonAlphanumeric = false;
                    options.Password.RequireUppercase = false;
                    options.Password.RequiredUniqueChars = 0;
                })
                .AddRoles<IdentityRole>()
                .AddEntityFrameworkStores<ApplicationDbContext>();
            services
                .AddRazorPages()
                .AddRazorRuntimeCompilation();

            services.AddAutoMapper(typeof(Startup));

            services.AddTransient<IdentitySeed>();
            services.AddTransient<DataSeed>();
            services.AddSingleton<IClockService, ClockService>();

        }

        public void ConfigureContainer(ContainerBuilder builder)
        {
            builder.RegisterSharpRepository(Configuration.GetSection("sharpRepository"), "efCore"); // for Ef Core
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseDatabaseErrorPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
            }

            app.UseStaticFiles();

            app.UseRouting();

            app.UseForwardedHeaders(new ForwardedHeadersOptions
            {
                ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
            });

            app.UseAuthentication();
            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapRazorPages();
            });

            // Passes service provide to SharpRepository
            // https://github.com/SharpRepository/SharpRepository/blob/develop/SharpRepository.Samples.Core3Mvc/Startup.cs
            RepositoryDependencyResolver.SetDependencyResolver(app.ApplicationServices);
        }
    }
}

@VictorioBerra
Copy link
Author

Got it, I forgot to register as transient... why is this needed?

@omarpiani
Copy link
Member

Trasient means that every time you resolve, container will instantiate a new object

@VictorioBerra
Copy link
Author

Right, but default is scoped, why change it?

@omarpiani
Copy link
Member

sorry for late reply.
Because it will avoid dbcontext disposed issues, obviously you risk to encouter the opposite problem when you are updating data connected from 2 different repositories.

@omarpiani
Copy link
Member

I'm releasing as stable this .NET Core 3 compatible packages

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants