How can i implement a Repository pattern with ASP.NET Core Identity?
I found a solution to implement a Repository pattern with ASP.NET Core, but not if you are also using the Identity framework.
The only thing i read is about using a two separate databases: one for Identity tables and another for bussiness data, but i'd like to know if it is possible to implement a repository pattern for a single database on a ASP.NET Core project with Identity.
you can use Autofac as your Dependency Injection in asp.net core. here's the documentation on how to use Autofac in your Asp.net Identity Project: Doc
First Add Identity in your services in Startup.cs
services.AddIdentity<User,IdentityRole>().AddDefaultTokenProviders();
and so on you can register a module in your Service Layer (or Whatever you name it in the repository pattern) and configure them after you register DbContext and your Services:
var dbContextParameter = new ResolvedParameter((pi, ctx) => pi.ParameterType == typeof(IdentityDbContext),
(pi, ctx) => ctx.Resolve<DatabaseContext>());
builder.RegisterType<UserStore<User, IdentityRole<Guid>, DatabaseContext, Guid>>()
.As<IUserStore<User>>().WithParameter(dbContextParameter).InstancePerLifetimeScope();
builder.RegisterType<UserManager<User>>()
.As<UserManager<User>>().WithParameter(dbContextParameter).InstancePerLifetimeScope();
builder.RegisterType<SignInManager<User>>()
.As<SignInManager<User>>().WithParameter(dbContextParameter).InstancePerLifetimeScope();
builder.RegisterType<RoleStore<IdentityRole>>()
.As<IRoleStore<IdentityRole>>().WithParameter(dbContextParameter).InstancePerLifetimeScope();
the code above is the way to register the UserStore, you can make UserManager, SignInManager and other classes like this
note that you can register your Services as their implemented Interfaces like this:
var Service = Assembly.GetExecutingAssembly();
builder.RegisterAssemblyTypes(Service)
.AsImplementedInterfaces();
then you can inject identity services into your Service Constructor like this:
public UserService(Data.IRepositoryX<User> repository, IUnitOfWorkDatabaseContext unit, SignInManager<User> signInManager) : base(repository)
{
}
Related
I have two separate .net core library one for Database and other for Service. Following Repository Pattern, my main application (.Netcore web api) has only service reference as I don't want to expose my database to main project. So service has reference of Database and Wep API has reference of Service. For Service I can easily add the reference by using IServiceCollection
services.AddSingleton<IEmployeeServices, EmployeeServices>();
so I can call service from controller with dependency inject
private readonly IEmployeeServices _empServices ;
public EmployeeController(IEmployeeServices empServices)
{
_empServices = empServices;
}
I want to call Database from Service in same manner
private readonly DbContext _context ;
public EmployeeServices(DbContext context)
{
_context = context;
}
but then I need to assign it like following
services.AddSingleton<IDbContext , DbContext >();
so I have to add reference of Database project in my main project but I don't want to expose Database to Main Application.
So, how can I register the dependency of Database project?
You can create a different library just for this. Take a look at examples of Clean Architecture. The configuration of services is done in a dll called .Application and referenced by the WebApi. This way the WebApi does not know about any registered services, it just injects them into his ServiceCollection.
You can create a service collection extension class in your "services project"
You will need this nuget Microsoft.Extensions.DependencyInjection.Abstractions
using Microsoft.Extensions.DependencyInjection;
public static class MyServiceCollectionExtension
{
public static void AddDatabaseProjectServices(this IServiceCollection services)
{
services.AddSingleton<IDbContext,DbContext>();
}
}
And use it in your web-api project :
services.AddDatabaseProjectServices();
Now 2 remarks :
1 ) with this extension your web-api doesn't use database project code directly but still has implicit reference on it because of service project. That's how reference and sub reference work.
The only way to forbid is using internal class (class cannot be used outside of assembly) but you won't be able to inject dependency...
2 ) .net core has a bunch of methods for adding dbcontext so it's better to use them instead of manually AddDbContext
I can't figure out how to use an AspNet Core 3.1 Web Api with Service Fabric and Autofac, and also how to have it ready for a TestServer to run for integration/functional testing.
The documentation is very incomplete.
Autofac documentation shows how to modify Program.cs to build autofac container, but it does not mention anything about the Startup.cs class that all the web api have:
https://autofaccn.readthedocs.io/en/latest/integration/servicefabric.html
Also the only example that Autofac has for service fabric is not a web api: https://github.com/autofac/Examples/tree/master/src/ServiceFabricDemo
There are other questions without valid answers:
Service Fabric AspNet Core 3.1 Autofac WebHostBuilder
Does anybody have any example on how to achieve this?
I can achieve the following (please see my GitHub repository with the sample)
Service fabric with stateless AspNet Core WebApi project (dotnet core 3.1)
Using Microsoft Dependency Injection to register services
Using TestServer to run integration tests on the http endpoint, and able to overwrite dependency injection registrations in a clean way without having to create another Startup class
I want the exact same, but using Autofac as DI container.
UPDATE 1:
I can't add Autofac to a WebHostBuilder and the ConfigureServices(IServiceCollection services) must be void as per AspNet Core 3.1+, so this is where I'm stuck. How to replace MS Dependency Injection in my sample
Event after the bounty there is not an answer to this. Maybe it's not possible as service fabric requires WebHost and not generic host.
In any case, I managed to have it working with older versions. Here's my repository where I show a sample on how to run AspNetCore2.1 with DotNetCore2.1 (LTS) and Autofac under Service Fabric. I use the webhost builder, not the generic one.
https://gitlab.com/sunnyatticsoftware/training/sasw-aspnetcore-testing/-/tree/master/aspnetcore2_1_autofac_servicefabric
Still, it'd be nice to eventually have a valid answer to the question.
I have NO idea if this works for the TestServer. It does however work fine with during ordinary hosting.
The exact thing you are looking for would be this line: services.Replace(ServiceDescriptor.Singleton<IServiceProviderFactory<ContainerBuilder>>(new AutofacServiceProviderFactory(null)));
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
return new[]
{
new ServiceInstanceListener(
serviceContext => new KestrelCommunicationListener(
serviceContext,
(url, listener) =>
{
return WebHost
.CreateDefaultBuilder()
.ConfigureServices(services =>
{
services.Replace(ServiceDescriptor.Singleton<IServiceProviderFactory<ContainerBuilder>>(new AutofacServiceProviderFactory(null)));
services.AddSingleton(serviceContext)
})
.UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.UseUniqueServiceUrl | ServiceFabricIntegrationOptions.UseReverseProxyIntegration)
.UseStartup<TStartupType>()
.Build();
}))
};
}
Hope it helps, it took me quite a while to arrive at this solution.
Let's consider that I already have a package that returns UserIdentity based on HttpRequest. I want to create an ASP.NET Core project that uses my package in order to get ClaimIdentity object. How it could be done?
I think you can tell Asp.NET Core to use your custom Identity by applying it on the services middleware registration. Something like
services.AddDefaultIdentity<MyIdentityClass>()
Supposing that MyIdentityClass extends the IdentityUser class.
You can find more informations about how to customize the Identity [https://learn.microsoft.com/it-it/aspnet/core/security/authentication/customize-identity-model?view=aspnetcore-3.1](here in the Asp.NET Core documentation)
I've been reading several documents and articles on how to ServiceStack's Redis client, but all of them use the ServiceStack's AppHost method and their built-in Func IOC
But I don't want to mix different IOC containers in my project.
And besides I don't want to use any other ServiceStack component other than the Redis client. Therefore I wanted to inject a singleton instance of the IRedisClientsManager preferably through the RedisManagerPool factory, straight from the ConfigureServices method of Startup.cs
After a reviewing the code from the updated .NET Core Live Demos
I figured out a clean and simple way of doing it.
So in my ConfigureServices method I registered IRedisClientsManager like this
services.AddSingleton<IRedisClientsManager> (c =>
new RedisManagerPool(Configuration.GetSection("Redis-Host").Value));
of course in order to read from configuration in ConfigureServices you need to add a constructor to inject it to Startup
IConfiguration Configuration { get; set; }
public Startup(IConfiguration configuration) => Configuration = configuration;
I am using ASP.NET Core with EF Core Code First.
I am defining the dependency injection of the DbContext in service configuration of the Startup.cs of my ASP.NET Core project like described here (https://docs.efproject.net/en/latest/platforms/aspnetcore/new-db.html):
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<TestContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DevelopmentDatabase")));
}
But I do not want to use the DbContext in a controller like described at the same site but I want to outsource it to another .NET Core Class Library project together with the Migration.
How do I accomplish this?
Implement the Repository Pattern
It's explained clearly here: Building Your First Web API with ASP.NET Core MVC
But register your repository as:
services.AddScoped<ICustomerRepository, CustomerRepository>();
instead of using .AddSingleton as the link suggests, to avoid this other problem.
I just put my xxxDbContext in a dll library project, but decided to keep migrations in the asp project:
protected override void OnConfiguring(DbContextOptionsBuilder b)
{
base.OnConfiguring(b);
b.UseSqlServer("Data Source=...", x => x.MigrationsAssembly("WebApp1"));
If you don't use MigrationsAssembly, your migrations should go to the dll I believe.
But I'm having problems using the dll in another project, I can't initiate a connection to the database