IAbpSession, ILogger, UserManager, How to inject these object in normal C# classes - asp.net-core-1.1

Is it possible to get instances of the below objects in normal C# classes:
IAbpSession, ILogger, UserManager, IConfigurationRoot
I want to use the object types in my custom classes which are not derived from other base classes. If not possible what base class should I derive my classes to have these object injected to my classes other than "MVC controllers", "Web API controllers" and "Application service"?

To use those interfaces in normal (your custom) C# classes you have to use dependency injection. First, you need to register your custom class in dependency injection system. It's very easy; Just inherit your custom class from ITransientDependency (or ISingletonDependency) and then inject IAbpSession or whatever class that's registered to dependency injection system. Let me show you a basic sample;
using Abp.Dependency;
using Abp.Runtime.Session;
using Castle.Core.Logging;
using Microsoft.Extensions.Configuration;
using MyCompanyName.AbpZeroTemplate.Authorization.Users;
public class MyCustomClass : ITransientDependency
{
private readonly IAbpSession _abpSession;
private readonly ILogger _logger;
private readonly UserManager _userManager;
private readonly IConfigurationRoot _configurationRoot;
public MyCustomClass(IAbpSession abpSession,
ILogger logger,
UserManager userManager,
IConfigurationRoot configurationRoot)
{
_abpSession = abpSession;
_logger = logger;
_userManager = userManager;
_configurationRoot = configurationRoot;
}
public async void CreateUser()
{
await _userManager.CreateAsync(new User
{
Name = "Alper",
TenantId = _abpSession.TenantId
}, "1234567");
var myConnectionString = _configurationRoot.GetConnectionString("Default");
_logger.Debug("A new user is created using this connection string : " + myConnectionString);
}
}
I tried to use all the interfaces that you mention.

Related

Extending UserManager results in ObjectDisposedException

If I extend the generated aspnetboilerplate UserManager class (from the startup template), any time I use the RoleManager I receive a ObjectDisposedException exception. I assume this is related to dependency injection. Is there something obvious I am doing wrong (or should not be doing)?
Here is the UserManager class definition (with the method I added at the bottom)
namespace MyProject.Authorization.Users
{
public class UserManager : AbpUserManager<Role, User>
{
public UserManager(
RoleManager roleManager,
UserStore store,
IOptions<IdentityOptions> optionsAccessor,
IPasswordHasher<User> passwordHasher,
IEnumerable<IUserValidator<User>> userValidators,
IEnumerable<IPasswordValidator<User>> passwordValidators,
ILookupNormalizer keyNormalizer,
IdentityErrorDescriber errors,
IServiceProvider services,
ILogger<UserManager<User>> logger,
IPermissionManager permissionManager,
IUnitOfWorkManager unitOfWorkManager,
ICacheManager cacheManager,
IRepository<OrganizationUnit, long> organizationUnitRepository,
IRepository<UserOrganizationUnit, long> userOrganizationUnitRepository,
IOrganizationUnitSettings organizationUnitSettings,
ISettingManager settingManager)
: base(
roleManager,
store,
optionsAccessor,
passwordHasher,
userValidators,
passwordValidators,
keyNormalizer,
errors,
services,
logger,
permissionManager,
unitOfWorkManager,
cacheManager,
organizationUnitRepository,
userOrganizationUnitRepository,
organizationUnitSettings,
settingManager)
{
}
public void GoBoom()
{
var role = RoleManager.Roles.FirstOrDefault();
}
}
}
Usage (here, directly injected and used on a razor view)
#inject MyProject.Authorization.Users.UserManager _userManager
#{
_userManager.GoBoom();
}
Add [UnitOfWork] attribute and make it a virtual method:
[UnitOfWork]
public virtual void GoBoom()
{
...
}
See: UnitOfWork Attribute Restrictions
You can use UnitOfWork attribute for:
All public or public virtual methods for classes that are used over an interface (Like an application service used over a service interface).
All public virtual methods for self-injected classes (Like MVC Controllers and Web API Controllers).
All protected virtual methods.

Spring - Access a Service interface programmatically

i have several interfaces which extend a single interface.
I need to add, during a #PostCostruct method, these interfaces to a Map.
The problem is that i need to retrieve the #Service class name from the DB and i don't know ho to put the interface in the map...
I'll try to explain it better
I have a general service interface
public interface IVehicleServiceGeneral{
//methods...
}
then i have several interfaces which extend the general one.
public interface IService1 extends IVehicleServiceGeneral{
}
public interface IService2 extends IVehicleServiceGeneral{
}
the concrete implementations of these classes are annotated with #Service("service1Name"), #Service("service2Name") and so on...
Then from the DB i retrieve my Suppliers
public class Supplier {
private long id;
private String serviceName;
//getters and setters
}
Finally i need to create the map, because i need to access the implementations at runtime based on the Supplier, i created a ContextAware class to get my beans by name, but the interfaces are not beans... I also tried to put the #Qualifier on the interface, but obviously it does not work... How can I put the interface in the map?
#PostConstruct
private void createServiceMap(){
serviceMap = new HashMap<OBUSupplier, IVehicleServiceGeneral>();
List<Supplier> suppliers = supplierService.findAll();
for(Supplier s : suppliers) {
serviceMap.put(s, contextAware.getBean(s.getServiceName()));
}
}
You can create IVehicleServiceGeneral instance map like this:
class SomeClass {
Map vehicleServiceGeneralInstanceMap = new HashMap();
SomeClass(Set<IVehicleServiceGeneral> instances) {
instances.forEach(i -> vehicleServiceGeneralInstanceMap.put(i.getServiceName(), i));
}
private void createServiceMap() {
Map serviceMap = new HashMap<OBUSupplier, IVehicleServiceGeneral>();
List<Supplier> suppliers = supplierService.findAll();
for(Supplier s : suppliers) {
serviceMap.put(s, vehicleServiceGeneralInstanceMap.get(s.getServiceName()));
}
}
The only thing you require is IVehicleServiceGeneral#getServiceName which your Service1, 2 need to override with proper names that present in DB.

Ninject Binding Issue with Constructor Chaining

I have a MVC3 project that uses the Entity Framework and Ninject v2.2, and follows the Unit of Work pattern with a Service Layer wrapping my repositories.
After looking at the code below, hopefully its apparent that Ninject is using constructor chaining to inject the correct classes. It currently works prefectly in my application, however I am at the point that I need to bind an instance of IDatabase to MyDatabase with a different scope such as InSingletonScope() or InNamedScope(), not InRequestScope(). I know that I can use the [Named("MyDatabaseScope")] Attribute to customize which IDatabase object is injected, however it seems that with my code structure, if I wanted to inject my SingletonScoped instance, I would have to recreate a new Abstract and Concrete Implementation of my Unit of Work, my Service and all my Repositories, that will then chain down.
Basically my application currently goes
Controller -> Unit of Work -> Database, (Repositories -> Database)
If I have to change my Database Binding, I will now have to create another chain in addition to the current one:
Controller -> New Unit of Work -> SingletonDatabase, (New Repositories-> SingletonDatabase)
This seems to completely defeat the DRY principal. Is there a way to, from the Controller Constructor, inform Ninject that when doing constructor chaining it should use my singleton (or named binding) rather than my request scope binding, without having to recreate all my classes with a Named attribute, or a new Interface?
Sorry for the long text, I wasnt sure if I could get the point across without my code snippets and my somewhat rambling explaination.
Ninject Module Load Function:
..snip..
Bind<IUserServices>().To<UserServices>();
Bind<IBaseServices>().To<BaseServices>();
Bind<IUserRepository>().To<UserRepository>();
Bind(typeof (IRepository<>)).To(typeof (RepositoryBase<>));
Bind<IUnitOfWork>().To<UnitOfWork>();
Bind<IDatabase>().To<MyDatabase>().InRequestScope();
//This is my problem:
//Bind<IDatabase>().To<MySingletonDatabase>().InSingletonScope();
Unit of Work Implementation Constructor:
public class UnitOfWork : IUnitOfWork
{
private IDatabase _database;
public UnitOfWork(IDatabase database,
IUserRepository userRepository,
IPeopleRepository peopleRepository,
)
{
this._database = database;
this.UserRepository = userRepository;
this.PeopleRepository = peopleRepository;
}
protected IDatabase Database
{
get { return _database; }
}
...snip...
}
User Service Layer Implementation Constructor:
public class UserServices : BaseServices, IUserServices
{
private IUnitOfWork _uow;
public UserServices(IUnitOfWork uow)
: base(uow)
{
_uow = uow;
}
...snip...
}
User Repository Constructor:
public class UserRepository : RepositoryBase<User>, IUserRepository
{
public UserRepository(IDatabase database)
: base(database)
{
}
...snip...
}
Controller Constructor:
public IUserServices _userServices { get; set; }
public ActivityController(IUserServices userServices)
{
_userServices = userServices;
}
}
Using Ninject 3.0.0 you can use WhenAnyAncestrorNamed("Some name") But if you need to run asyncronous things you should thing about splitting your application into a web frontend and a server backend. This could make many things easier.

Where should I create the Unit of Work instance in an ASP.Net MVC 3 application?

I have read as many of the posts on Stackoverflow as I can find with regards the use of a Unit of Work pattern within
an ASP.Net MVC 3 application which includes a Business Layer. However, I still have a couple of questions with
regards this topic and would greatly appreciate any feedback people can give me.
I am developing an ASP.Net MVC 3 Web application which uses EF 4.1. I will be using both the Repository and
Unit of Work Patterns with this project similar to how they are used in this great tutorial
The difference in my project is that I need to also include a Business Layer (separate project in my solution) in order to
carry out the various business rules for the application. The tutorial mentioned above does not have a Business layer, and
therefore creates an instance of the Unit of Work class from the controller
public class CourseController : Controller
{
private UnitOfWork unitOfWork = new UnitOfWork();
However, my question is, where should I create the instance of the Unit of Work class if I have a Business Layer?
I personally think it should be created in my controller and then injected into the Business Layer like so:
public class PeopleController : Controller
{
private readonly IUnitOfWork _UoW;
private IPersonService _personService;
public PeopleController()
{
_UoW = new UnitOfWork();
_personService = new PersonService(_UoW);
}
public PeopleController(IUnitOfWork UoW, IPersonService personService)
{
_UoW = UoW;
_personService = personService;
}
public ActionResult Edit(int id)
{
Person person = _personService.Edit(id);
return View(person);
}
public class UnitOfWork : IUnitOfWork, IDisposable
{
private BlogEntities _context = new BlogEntities();
private PersonRepository personRepository = null;
public IPersonRepository PersonRepository
{
get
{
if (this.personRepository == null)
{
this.personRepository = new PersonRepository(_context);
}
return personRepository;
}
}
public void Save()
{
_context.SaveChanges();
}
public class PersonService : IPersonService
{
private readonly IUnitOfWork _UoW;
public PersonService(IUnitOfWork UoW)
{
_UoW = UoW;
}
public Person Edit(int id)
{
Person person = _UoW.PersonRepository.GetPersonByID(id);
return person;
}
public class PersonRepository : IPersonRepository
{
private readonly BlogEntities _context;
public PersonRepository(BlogEntities context)
{
_context = context;
}
public Person GetPersonByID(int ID)
{
return _context.People.Where(p => p.ID == ID).Single();
}
I have read others saying that the Unit of Work instantiation should not be in the Controller, but created in the Service Layer
instead. The reason why I am not so sure about this approach is because my Controller may have to use several different
Service Layers in one business transaction, and if the Unit of Work instance was created inside each Service, it would result in several
Unit of Work instances being created, which defeats the purpose, ie, one Unit of Work per business transaction.
Maybe what I have explained above is wrong, but if so, I would greatly appreciate if someone could put me right.
Thanks again for your help.
I think you have a couple of changes to make:.
Allow your DI container to inject a UnitOfWork instance into your Service classes in their constructors, and leave it out of your Controller altogether.
If your DI container supports it (Ninject does, for example), configure your UnitOfWork to be managed on a per-request basis; this way your services will be handed a distinct UnitOfWork for each request, and you're all done. Or...
If your DI container does not support per-request lifetimes, configure it to manage the UnitOfWork as a singleton, so every Service class gets the same instance. Then update your UnitOfWork to store its Entities object in a data store which stores objects on a per-request basis, for example in HttpContext.Current.Items, as described here.
Edit 1
Regarding where the UnitOfWork should be injected; I'd say the Service layer is the correct place. If you imagine your system as a series of layers where the outer layers deal with user interactions and the lower layers deal with data storage, each layer should become less concerned with users and more concerned with data storage. UnitOfWork is a concept from one of the 'lower-level' layers and Controller is from a higher-level layer; your Service layer fits between them. It therefore makes sense to put the UnitOfWork into the Service class rather than the Controller.
Edit 2
To elaborate on the UnitOfWork creation and it's relationship to HttpContext.Current.Items:
Your UnitOfWork would no longer hold a reference to an Entities object, that would be done through the HttpContext object, injected into the UnitOfWork behind an interface like this:
public interface IPerRequestDataStore : IDisposable
{
bool Contains(string key);
void Store<T>(string key, T value);
T Get<T>(string key);
}
The HttpContext object would then implement IPerRequestDataStore like this:
public class StaticHttpContextPerRequestDataStore : IPerRequestDataStore
{
public bool Contains(string key)
{
return HttpContext.Current.Items.Contains(key);
}
public void Store<T>(string key, T value)
{
HttpContext.Current.Items[key] = value;
}
public T Get<T>(string key)
{
if (!this.Contains(key))
{
return default(T);
}
return (T)HttpContext.Current.Items[key];
}
public void Dispose()
{
var disposables = HttpContext.Current.Items.Values.OfType<IDisposable>();
foreach (var disposable in disposables)
{
disposable.Dispose();
}
}
}
As an aside, I've called it StaticHttpContextPerRequestDataStore as it uses the static HttpContext.Current property; that's not ideal for unit testing (another topic altogether), but at least the name indicates the nature of its dependency.
Your UnitOfWork then passes the IPerRequestDataStore it's given to each of its Repository objects so they can access the Entities; this means that no matter how many UnitOfWork instances you create, you'll use the same Entities object throughout a request because it's stored and retrieved in the IPerRequestDataStore.
You'd have an abstract base Repository which would use its IPerRequestDataStore to lazy-load its Entities object like this:
public abstract class RepositoryBase : IDisposable
{
private readonly IPerRequestDataStore _dataStore;
private PersonRepository personRepository;
protected RepositoryBase(IPerRequestDataStore dataStore)
{
this._dataStore = dataStore;
}
protected BlogEntities Context
{
get
{
const string contextKey = "context";
if (!this._dataStore.Contains(contextKey))
{
this._dataStore.Store(contextKey, new BlogEntities());
}
return this._dataStore.Get<BlogEntities>(contextKey);
}
}
public void Dispose()
{
this._dataStore.Dispose();
}
}
Your PeopleRepository (for example) would look like this:
public class PeopleRepository : RepositoryBase, IPersonRepository
{
public PeopleRepository(IPerRequestDataStore dataStore)
: base(dataStore)
{
}
public Person FindById(int personId)
{
return this.Context.Persons.FirstOrDefault(p => p.PersonId == personId);
}
}
And finally, here's the creation of your PeopleController:
IPerRequestDataStore dataStore = new StaticHttpContextDataStore();
UnitOfWork unitOfWork = new UnitOfWork(dataStore);
PeopleService service = new PeopleService(unitOfWork);
PeopleController controller = new PeopleController(service);
One of the central concepts here is that objects have their dependencies injected into them via their constructors; this is generally accepted as good practice, and more easily allows you to compose objects from other objects.

Ninject and Provider Model with Parameterless Constructor

I am implementing a custom RoleProvider and would like to use Ninject however I am faced with a parameterless constructor issue. Any thoughts on how to inject for this??
public class EFRoleProvider:RoleProvider
{
private readonly IRepository _repository;
// I want to INJECT this GOO here!
public EFRoleProvider()
{
IContextFactory contextFactory = new DbContextFactory<myEntities>();
_repository = new RepositoryBase(contextFactory);
}
}
You cannot inject something that is hardcoded. Sorry. No DI framework supports this. In your constructor you have hardcoded the instance, so this is no longer inversion of control. In order to perform inversion of control you need to define your layers as loosely coupled as possible:
public class EFRoleProvider: RoleProvider
{
private readonly IContextFactory _contextFactory;
public EFRoleProvider(IContextFactory contextFactory)
{
_contextFactory = contextFactory;
}
}
Now go ahead and configure your DI framework.

Resources