Ninject: Construct all classes that inherit from an abstract class that also pass some custom Boolean logic - ninject

I am looking to find out how to use Ninject to get all instances that inherit from a base class that also pass some custom Boolean criteria. This is a continuation of a previous question. This is how I am creating a binging for all classes that inherit from MyAbstractClass.
_kernel.Bind(x => { x
.FromThisAssembly()
.SelectAllClasses()
.InheritedFrom<MyAbstractClass>()
.BindAllBaseClasses()
.Configure(syntax => syntax.InSingletonScope());
});
If I have the syntax correct, this will create a singleton scope binding for all classes that inherit from MyAbstractClass. Next I need to get/construct all the classes.
IEnumerable<MyAbstractClass> items = kernel.GetAll<MyAbstractClass>();
The code above will get/create all classes that inherit from MyAbstractClass.
Now I need to add one more step to this process. Based on “access roles” not all classes that inherit from MyAbstractClass should be created because the current user might not have access to functionality for every derived class. So I tried adding a CanLoad Boolean to each derived class and tried the following.
IEnumerable<MyAbstractClass> items = kernel.GetAll<MyAbstractClass>().Where(x => x.CanLoad == true);
While items did contain only the classes I expected, based on my CanLoad logic, I did see the constructor for each derived class being called because of the kernel.GetAll() method. Also it will have to create the class to call its CanLoad method, so that will not work. I thought about making the CanLoad static too. I also thought about a method that would look similar to the following.
public bool CanLoad<T>() where T : MyAbstractClass {
//return true if the current user has the correct access roles to create class of type T
}
So my question is how can I use the Ninject GetAll() method to get all classes that inherit from MyAbstractClass that also return true for the CanLoad Boolean method? I have been trying to use Ninject and Linq and possibly Reflection but I do not have a solution yet.
Edit:
To elaborate on the “permission logic”, at the very beginning our app calls out to a web service to get a list of LDAP groups/roles which are returned as a simple list of string. Each of the derived classes are actually ViewModels and each ViewModel “needs” a minimum role for its functionality to be usable by the current user. I thought I could tie the Ninject/binding/get logic with some custom “permission logic” and only bind/get classes the current user has access to. The list of VMs become an ItemsSource binding for a docking control (and we are considering using creating an ItemsSource binding for the Ribbon control as well). It’s all research at this point.

Add a When constraint to the binding:
.Configure(syntax => syntax
.When(... check permission here...)
.InSingletonScope());
Since you didn't say anything about the logic how you know whether the user has permission, i can't give you more specific information here. But generally speaking, you should add a 'When' constraint to your binding whenever you want to make sure it cannot and will not be instanciated unless a condition is met.

Related

Having more than one entity context

Let's say I've extended identity framework dbContext to build my own, and I've our authenticated controller who get injected with the dbContext and fetch an entity related with the current ApplicationUser, entity framework will relate the two entities leading to a server error because of circular references.
We don't want to serialize circular references.
So we create a new dbContext in the method who istantiate a new dbcontext and query the unrelated entities, this will work. But this is not testable, we don't want our controller to strictly depends on the dbContext, we want it to be injected.
So we add a second parameter, in the constructor, unfortunately this will make the system inject the same dbContext twice, not so useful.
We tried to create a class fakeDbContext who inherit from dbContext and add it services and use it, but now we got two dbcontext, who can potentially generate migrations and configurations and errors...
Which is the right way of doing this in the new MVC6 ?
Edit...
I found out that if my controller require an IEnumerable<dbContext> i get all the object registered as service of that type, so just doubling the part in startup.cs where we add the dbContext in the service registration area i get two of them...
The drawback here is that i don't know wich one is the virgin one, it looks like it goes in order of registration, but i have no clue, if this will change.
Edit 2 ...
I've created a TransientDbService class who have just a factory method taking the IserviceProvider, it use it to get the options to construct the dbContext, and then expose it. I've registered it as transient, then in the controller i require this service type.
the drawback here is if i'll ever need a third dbContext i should write more code, more code means errors and maintaning it.
Edit 3 ...
Not having two dbContext at all. The following setting allow me to have no relationships valorized.
Database.ChangeTracker.QueryTrackingBehavior = Microsoft.Data.Entity.QueryTrackingBehavior.NoTracking;
The drawback here is that i can't use my model graph, making everything more complex...
Edit 4 ...
https://github.com/aspnet/DependencyInjection/issues/352
You are right to think that no tracking queries will help in some cases, but other times you'll need to have more than one instance of the DbContext created.
You normally use the AddDbContext<TContext>() method in startup to make sure an instance of your context type is created per request and the right DbContextOptions and service provider get set on it. When you need to deviate from this pattern you have a few options, e.g.:
Include a constructor in your derived DbContext class that takes an IServiceProvider and passes it to the base constructor. Make sure your controller takes IServiceProvider. Once you do this you should be able to create DbContext manually with something like this:
using(var context1 = new MyDbContext(serviceProvider),
var context2 = new MyDbContext(serviceProvider))
{ ...
To avoid having to change the constructor signatures on your derived DbContext type you can take advantage of the DbContextActivator class (it is our Internal namespace), e.g.:
using(var context1 = DbContextActivator.CreateInstance<MyDbContext>(serviceProvider),
var context2 = DbContextActivator.CreateInstance<MyDbContext>(serviceProvider)
{...
Note: If you are still using AddDbContext<MyDbContext>(options => ...) in startup it should pull those options automatically from the service provider. But you can also choose to either include the DbContextOptions as a parameter in the constructor or override the OnConfiguring() method for that.
I am giving you examples that create two separate DbContexts in a using block, but you should also be able to mix those with the regular "per-request" DbContext you would get injected in the controller's constructor.
Besides these options currently available I have created a new issue to track other possible improvements on how to create multiple instance of the same DbContext type in the same request:
https://github.com/aspnet/EntityFramework/issues/4441

Expose only a part of my class

Lets say i have a Class User with multiple properties. I'm building a REST based App so in my homepage when I request for "user details" I need only a few properties from my User and rest from other classes. How do i write the class for the object which i would return for "user details" ?
My current design retrieves the needed properties from the class to build the JSON. I hope there is a better way to handle this.
I use Play Framework 2.0 with Java
If you don't want to expose whole business class User, I'll build a second class, a DTO. This class provides only the desired data to be transfered by REST API.
User user = new User("admin");
// Set other properties
UserDetailsDTO userDetailsDTO = new UserDetails(user); //<- Transfer userDetailsDTO
Or if "user details" are important for your application, maybe you should consider to create a UserDetails class and use it inside your User class by composition.
public class User {
Long id;
String name;
String address;
UserDetails userDetails; // Composition <- Tranfer userDetails
}
Note: example where don in Java
Looks like you need a Facade: http://en.wikipedia.org/wiki/Facade_pattern.
It is a simple pattern that helps you expose methods/properties from a multiple classes.
You can store references to objects in your Facade class and expose only those things you need.
There is an option of creating a View Model object, providing proper abstraction for the information required for that JSON.
More details about it here: http://en.wikipedia.org/wiki/Model_View_ViewModel
But this is typically used in the cases where view directly used in Views of the application. So careful analysis is required in use case mentioned above, since there is already JSON being created, creation of this View Model layer is really justified.

Where to put methods that interact with multiple classes

I have a class called Contact and one called Account
and I have a method called public static Account GetAccount(Contact c) {...}
Where is the best place to put this method? What design patterns should I be looking at?
A) With the Contact class
B) With the Account class
C) Have the method accessible in both classes
D) Somewhere else?
There are probably many good answers to your question. I'll take a stab at an answer, but it will have my personal biases baked in it.
In OOP, you generally don't see globally accessible) functions, disconnected from, but available to all classes. (Static methods might be globally available, but they are still tied to a particular class). To follow up on dkatzel's answer, a common pattern is in OOP is instance manager. You have a class or instance that provides access to a a database, file store, REST service, or some other place where Contact or Account objects are saved for future use.
You might be using a persistence framework with your Python project. Maybe something like this: https://docs.djangoproject.com/en/dev/topics/db/managers/
Some persistence frameworks create handy methods instance methods like Contact.getAccount() -- send the getAccount message to a contact and the method return the associated Account object. ...Or developers can add these sorts of convenience methods themselves.
Another kind of convenience method can live on the static side of a class. For example, the Account class could have a static getAccountForContact() method that returns a particular account for a given Contact object. This method would access the instance manager and use the information in the contact object to look up the correct account.
Usually you would not add a static method to the Contact class called getAccountForContact(). Instead, you would create an instance method on Contact called getAccount(). This method could then call Account.getAccountForContact() and pass "self" in as the parameter. (Or talk to an instance manager directly).
My guiding principle is typically DRY - do not repeat yourself. I pick the option that eliminates the most copy-and-paste code.
If you define your method in this way, it's not really connected with either of your classes. You can as well put it in a Util class:
public class AccountUtil{
public static Account getAccount(Contact c){ ... }
// you can put other methods here, e.g.
public static Contact getContact(Account a){ ... }
}
This follows the pattern of grouping static functions in utility classes like Math in Java / C#.
If you would like to bound the function to a class in a clear way, consider designing your class like this:
public class Contact{
public Account getAccount(){ ... } // returns the Account of this Contact
// other methods
}
In OOP it is generally recommended that you avoid using global functions when possible. If you want a static function anyways, I'd put it in a separate class.
It depends on how the lookup from Contact to Account happens but I would vote for putting it in a new class that uses the Repository pattern.
Repository repo = ...
Account account = repo.getAccount(contact);
That way you can have multiple Repository implemtations that look up the info from a database, or an HTTP request or internal mapping etc. and you don't have to modify the code that uses the repositories.
My vote is for a new class, especially if the function returns an existing account object. That is, if you have a collection of instances of Contact and a collection of instances of Account and this function maps one to the other, use a new class to encapsulate this mapping.
Otherwise, it probably makes sense as a method on Contact if GetAccount returns a new account filled in from a template. This would hold if GetAccount is something like a factory method for the Account class, or if the Account class is just a record type (instances of which have lifetimes which are bound to instances of Contact).
The only way I see this making sense as part of Account is if it makes sense as a constructor.

In Ninject 2.0, how do I have both a general binding and a binding for a specific case?

I have a situation where I want to dependency inject my user object, but also place the current user in the IoC container. I want the following lines to work:
kernel.Get<User>(); // Should return a new User()
kernel.Get<User>("Current"); // Should return the current user
One might think bindings like this would work:
Bind<User>().ToSelf();
Bind<User>().ToMethod(LoadCurrentUser).InRequestScope().Named("Current");
Of course, that gives:
Ninject.ActivationException: Error activating User
More than one matching bindings are available.
Activation path:
1) Request for User
Suggestions:
1) Ensure that you have defined a binding for User only once.
I understand the error since a Named binding does not restrict the application of that binding, so both bindings apply. It seems clear that I need to use the contextual bind with the .When*() methods but I can't come up with any way to do that. I feel like there should be when methods that detect whether a named instance is applied. Something like:
// Not valid Ninject syntax
Bind<User>().ToSelf().WhenUnnamedRequested();
Bind<User>().ToMethod(LoadCurrentUser).WhenNamedRequested().InRequestScope().Named("Current");
I can't find any place on the IRequest interface or it's properties that tells me the name requested. How do I do this?
This question was answerd on the mailing list:
http://groups.google.com/group/ninject/browse_thread/thread/cd95847dc4dcfc9d?hl=en
If you are accessing the user by calling Get on the kernel (which I hope you do not) then give the first binding a name as well and access User always by name. Actually, there is a way to get an instance from the binding without a name. But because I heartily recommend not to do this, I do not show how to to this here. If you still want to do it this way I'll tell you later how this would work.
If you are doing it the better and prefered way and inject the user to the objects that require it as dependency there are two options:
The easier one: Give the first binding a name and add a named attribute to the parameters e.g. ctor([Named("NewUser") IUser newUser, [Named("Current")] IUser
currentUser)
Or the prefered way to keep the implementation classes free of the IoC framework: Specify custom attributes and add them to the parameters e.g. ctor([NewUser] IUser newUser, [CurrentUser]IUser currentUser). Change the Bindings to:
Bind<User>().ToSelf()
.WhenTargetHas<NewUserAttribute>();
Bind<User>().ToMethod(LoadCurrentUser)
.InRequestScope()
.WhenTargetHas<CurrentUserAttribute>();

Does dependency injection increase my risk of doing something foolish?

I'm trying to embrace widespread dependency injection/IoC. As I read more and more about the benefits I can certainly appreciate them, however I am concerned that in some cases that embracing the dependency injection pattern might lead me to create flexibility at the expense of being able to limit risk by encapsulating controls on what the system is capable of doing and what mistakes I or another programmer on the project are capable of making. I suspect I'm missing something in the pattern that addresses my concerns and am hoping someone can point it out.
Here's a simplified example of what concerns me. Suppose I have a method NotifyAdmins on a Notification class and that I use this method to distribute very sensitive information to users that have been defined as administrators in the application. The information might be distributed by fax, email, IM, etc. based on user-defined settings. This method needs to retrieve a list of administrators. Historically, I would encapsulate building the set of administrators in the method with a call to an AdminSet class, or a call to a UserSet class that asks for a set of user objects that are administrators, or even via direct call(s) to the database. Then, I can call the method Notification.NotifyAdmins without fear of accidentally sending sensitive information to non-administrators.
I believe dependency injection calls for me to take an admin list as a parameter (in one form or another). This does facilitate testing, however, what's to prevent me from making a foolish mistake in calling code and passing in a set of NonAdmins? If I don't inject the set, I can only accidentally email the wrong people with mistakes in one or two fixed places. If I do inject the set aren't I exposed to making this mistake everywhere I call the method and inject the set of administrators? Am I doing something wrong? Are there facilities in the IoC frameworks that allow you to specify these kinds of constraints but still use dependency injection?
Thanks.
You need to reverse your thinking.
If you have a service/class that is supposed to mail out private information to admins only, instead of passing a list of admins to this service, instead you pass another service from which the class can retrieve the list of admins.
Yes, you still have the possibility of making a mistake, but this code:
AdminProvider provider = new AdminProvider();
Notification notify = new Notification(provider);
notify.Execute();
is harder to get wrong than this:
String[] admins = new String[] { "joenormal#hotmail.com" };
Notification notify = new Notification(admins);
notify.Execute();
In the first case, the methods and classes involved would clearly be named in such a way that it would be easy to spot a mistake.
Internally in your Execute method, the code might look like this:
List<String> admins = _AdminProvider.GetAdmins();
...
If, for some reason, the code looks like this:
List<String> admins = _AdminProvider.GetAllUserEmails();
then you have a problem, but that should be easy to spot.
No, dependency injection does not require you to pass the admin list as a parameter. I think you are slightly misunderstanding it. However, in your example, it would involve you injecting the AdminSet instance that your Notification class uses to build its admin list. This would then enable you to mock out this object to test the Notification class in isolation.
Dependencies are generally injected at the time a class is instantiated, using one of these methods: constructor injection (passing dependent class instances in the class's constructor), property injecion (setting the dependent class instances as properties) or something else (e.g. making all injectable objects implement a particular interface that allows the IOC container to call a single method that injects its dependencies. They are not generally injected into each method call as you suggest.
Other good answers have already been given, but I'd like to add this:
You can be both open for extensibility (following the Open/Closed Principle) and still protect sensitive assets. One good way is by using the Specification pattern.
In this case, you could pass in a completely arbitrary list of users, but then filter those users by an AdminSpecification so that only Administrators recieve the notification.
Perhaps your Notification class would have an API similar to this:
public class Notification
{
private readonly string message;
public Notification(string message)
{
this.message = message;
this.AdminSpecification = new AdminSpecification();
}
public ISpecification AdminSpecification { get; set; }
public void SendTo(IEnumerable users)
{
foreach(var u in users.Where(this.AdminSpecification.IsSatisfiedBy))
{
this.Notify(u);
}
}
// more members
}
You can still override the filtering behavior for testing-purposes by assigning a differet Specification, but the default value is secure, so you would be less likely to make mistakes with this API.
For even better protection, you could wrap this whole implementation behind a Facade interface.