We are developing a Full Stack Authorised WebApi with Entity Framework and Identity 2.0.
Its based on a git repo here
WebApi Full Stack Entity Framework Repository
In our service layer we pass across the a custom interface from our context i.e.
private readonly Func<IGPFocusDataContext> _contextFactory;
public PatientService(Func<IGPFocusDataContext> contextFactory)
{
this._contextFactory = contextFactory;
}
I've created a similar UserService, its at this point I want to inject the UserManager and RoleManager interface in a similar way.
Can anyone recommend the best way of doing this?
Looking at the repo you can add the instances/implementations of UserManger and RoleManager to the Unity container in UnityConfig.cs something like:
container.RegisterType<UserManager, UserManager>();
Or
container.RegisterType<IUserManager, UserManager>();
And then in your UserService
private readonly IUserManger _userManger;
private readonly IRoleManger _roleManger;
public UserService(IUserManger userManger, IRoleManager roleManger)
{
this._userManager = userManger;
this._roleManger = roleManger;
}
When you add the service in your controller similar to the PatientService in PatientsController, although I am not familiair with Unity, I expect Unity ties it all together.
Related
About 3 years ago I build a Web API and created a generic repository with Ninject for DI. Today I'm reviewing my code to make some changes and I can't understand where my DbContext is being instantiated. I can't remember what I didn't, I believe this was a hybrid of a bunch of implementation I reading up on Generic Repo.
I've spent quite some time reading through documentation online but couldn't find an answer. Can someone please explain it to me so I can document it properly? Below is my sample generic repo, application repo, my controller and Ninject binding. I know in .net core you can inject it from the startup but this was web api 2 using EF6.
Generic Repo:
public GenericRepository(DbContext _context, ILogService _log)
{
this.context = _context;
entities = context.Set<T>();
}
Entity Repo:
public ApplicationRepository(TransactionDbContext context) : base(context)
{
}
Controller:
public ApplicationController(IApplicationRepository _applicationRepository)
{
this.applicationRepository = _applicationRepository
}
Ninject Binding:
kernel.Bind<IApplicationRepository>().To<ApplicationRepository>();
By default, Ninject allows you to auto-resolve concrete types.
For more information, you can read the Ninject wiki: https://github.com/ninject/ninject/wiki/Dependency-Injection-With-Ninject
I want to use Repository & Unit Of Work in my project.
But in ASP.NET MVC when we want use DBContext to use this code
MyDbContext db=new MyDbContext();
but in ASP.NET Core when write this code it want an argument
because use this code in DbContext Class
public MyDbContext(DbContextOptions<MyDbContext> options) : base(options) { }
Error:
what is the problem?
You can initilize your DB context like this:
var optionBuilder = new DbContextOptionsBuilder<MyDbContext>();
optionBuilder.UseSqlServer("Server=localhost;...");
var context = new MyDbContext(optionBuilder.Options);
Previous code is configuring the options to the connection and then creating a MyDbContext using those options.
If you want to use a InMemoryDatabase for unit testing for example you can change it to this:
var optionBuilder = new DbContextOptionsBuilder<MyDbContext>().UseInMemoryDatabase("testindDB")`;
public MyDbContext(DbContextOptions<MyDbContext> options)
You have not empty constructor in your MyDbContext class, So you should do pass parameter DbContextOptions<MyDbContext> options in constructor.
For example you can see it -> link1
You shouldn't be instantiating the DbContext, you should be requesting it as a constructor argument to your repository. Then your IOC container will provide the DbContext at runtime. This ensures that you can use the same DbContext throughout a given ASP.NET web request, which will prevent a host of problems you're otherwise likely to encounter.
You can see an example of a generic repository here:
http://deviq.com/repository-pattern/
You also typically don't need a separate Unit of Work in ASP.NET applications (but sometimes you do). This is because your requests should be very small and you should be able to do most of the work in a single controller or service, and then simply save through the repository. It's not that you never need UoW, but it's less necessary than in a thick client scenario (e.g. windows app or service).
You can try it: In your class UnitOfWork
private MyDBContext _context;
public UnitOfWork(MyDBContext context)
{
_context = context;
}
In your controller:
private UnitOfWork _unitOfWork;
public MoviesController(MyDBContext context)
{
_unitOfWork = new UnitOfWork(context);
}
I'd like to run some node code from my c#. Microsoft.AspNetCore.NodeServices seems to be the way to do this job however the examples are all very similar and all involve putting
services.AddNodeServices();
in the configure services function and then DI adds the implementation of INodeServices to a controller. Like this
public class foo
{
private readonly INodeServices _nodeServices;
public foo(INodeServices nodeServices)
{
_nodeServices = nodeServices;
}
}
As I'm using this in a class library rather than a webapi how is DI going to work? Also how do I call the class from a unit test, what can I pass into the constructor? I'm sure I'm missing something obvious.
The concept of DI is that it can be used to resolve object graphs. That is, it doesn't just resolve dependencies of the Controller class, but dependencies of those dependencies, dependencies of those dependencies, etc.
To use INodeServices in your own library, you simply need to reference Microsoft.AspNetCore.NodeServices, then accept it as a constructor parameter.
public class MyServiceFromMyLibrary : IMyServiceFromMyLibrary
{
private readonly INodeServices nodeServices;
public MyServiceFromMyLibrary(INodeServices nodeServices)
{
this.nodeServices = nodeServices;
}
// ...
}
Then reference your library from the Web API project and inject your service into a controller.
public class FooController
{
private readonly IMyServiceFromMyLibrary myService;
public FooController(IMyServiceFromMyLibrary myService)
{
this.myService = myService;
}
}
DI takes care of putting the INodeServices instance into your class provided it is registered in your composition root, as follows.
services.AddNodeServices();
services.AddTransient<IMyServiceFromMyLibrary, MyServiceFromMyLibrary>();
If your end game is to create a reusable library rather than an application layer refer to DI Friendly Library for some techniques to make your library easier to use without the use of dependency injection.
Also how do I call the class from a unit test, what can I pass into the constructor?
For a unit test, you would just need to mock INodeServices. The simplest way is to use a mocking library, such as Moq.
var mock = new Mock<INodeServices>();
mock.Setup(ns => ns.InvokeAsync(It.IsAny<string>())).Returns(...);
var target = new MyServiceFromMyLibrary(mock.Object);
// .. Call a method on target and then assert the results
References:
Using Node Services in ASP.NET Core
Dependency injection in ASP.NET Core
In an ASP.NET Core 1.0 project, using DI how can I pass parameters to constructor. For instance, how do I register the following service in Startup.cs. services.AddTransient(typeof(IStateService), new StateService()); does not work since StateService() requires an input parameter of type BlogingContext. Or, are there alternative way of building the following service with database involved? Here State is a table coming from SQL Server Db. App is using EntityFrameworkCore with Code First approach. I'm using latest release of ASP.NET Core 1.0 and VS2015-Update 3 released on June 27, 2016
I see a similar example here but not quite the same type of input parameter.
Service:
public interface IStateService
{
IEnumerable<State> List();
}
public class StateService : IStateService
{
private BloggingContext _context;
public StateService(BloggingContext context)
{
_context = context;
}
public IEnumerable<State> List()
{
return _context.States.ToList();
}
}
As documentation states here (Scroll a bit down) you should register the IStateService and BloggingContext like:
services.AddDbContext<BloggingContext>();
services.AddScoped<IStateService, StateService>();
Then DI will resolve the whole dependency tree for you. Note that you should use scoped lifetime on service, because the service should use same lifetime as DbContext and it uses scoped.
We are developing a web application in which the user can register orders, customers, etc. and later review them. We have services that are used by MVC controllers in order to interface with the web UI.
Now we face the problem of multiple users: each service should be provided the currently authorised user Id, so all operations (CRUD and bussiness logic) will only be allowed for that user id. How is it supposed to be passed?
I am thinking about having a parameter passed to my IDataService (base class for services), which is instantiated by the WhateverController, which in turn has access to the User.Identity.GetUserId() method, BUT as I am using an IoC container (Ninject) I don't know how to do that. I guess that IDataService needs a reference to a IUserInfoProvider, so it can call IUserInfoProvider.GetUserId(). Then I can inject somehow an implementation based on Identity and having the current web context information, pretty much in the same way that the Controller must be instantiated.
Question is: how to get that data?
A simpler solution, of course, would be to do it by hand in each Controller constructor, but there should be a more automatic and elegant way to solve this.
EDIT: After some more reasearch, thanks to the answer of Cuong Le, the question I had to ask was, in fact, "how to inject the UserManager from the current context?".
However, in order to decouple my services layer from MVC, I created an IUserInfoProvider, which provides access to the authenticated user data. The implementation based in Identity and the UserManager lies in the Web UI (MVC) project, so it has a IPrincipal as suggested by Cuong Le, and an ApplicationUserManager, all injected using Ninject.
The following interface abstract the user information from Identity and the UserManager.
public interface IUserInfoProvider<T>
{
string GetUserId();
T GetUserData();
}
Here is the implementation in the MVC project using Identity and UserManager.
public class IdentityUserInfoProvider : IUserInfoProvider<DatosEmpresa>
{
private readonly ApplicationUserManager _userManager;
private readonly IPrincipal _user;
public IdentityUserInfoProvider(ApplicationUserManager userManager, IPrincipal user)
{
_userManager = userManager;
_user = user;
}
public string GetUserId()
{
return _user.Identity.GetUserId();
}
public DatosEmpresa GetUserData()
{
return _userManager.FindById(_user.Identity.GetUserId()).DatosEmpresa;
}
}
And the Ninject configuration bit
kernel.Bind<IUserInfoProvider<DatosEmpresa>>().To<IdentityUserInfoProvider>();
kernel.Bind<IPrincipal>()
.ToMethod(ctx => HttpContext.Current.User)
.InRequestScope();
kernel.Bind<ApplicationUserManager>()
.ToMethod(ctx => HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>())
.InRequestScope();
Then I can use an IUserInfoProvider inside any service object and it gets the correct user.
The simple solution is you can put IPrincipal into NInject Container:
kernel.Bind<IPrincipal>().ToMethod(context => HttpContext.Current.User);
So in your ServiceBase you can inject IPrincipal via either property or contructor, like this:
class ServiceBase
{
[Inject]
public IPrincipal User { get; set; }
}
Now you can get information from this property.