Patterns for role-based behaviour - oop

I'm involved in an application migration project. This application is supposed to execute some logic based on the current user role, so this snippets like this are everywhere in the code:
if ("Role1".equals(user.getUserRole())){
operationVersionForRole1();
} else if ("Role2".equals(user.getRole())){
operationVersionForRole2();
} else if ("Role3".equals(user.getRole())){
operationVersionForRole3();
}
There are about five roles and almost fifty operations, and some operations are very complex for some roles (almost 1000 lines of code) so that style of programming makes the source code messy and hard to follow. Is there any know design pattern that helps to organize source code in that situations? Nested "if-else" just doesn't feel right.

Isn't it a Abstract Factory that provides an interface for creating families of related or dependent objects without specifying their concrete class? Specified role will be an argument to create concrete implementation. And operationVersionForRoleX could be designed as different implementation or strategy of IOperation interface.
interface IOperation
{
void Execute();
}
class OperationVersionForRoleX : IOperation
{
public void Execute()
{
// …
}
}
string role = "roleX";
IOperation operation = operationFactory.Create(role);
operation.Execute();

Simmilar to what casablanca has answered.
I usually avoid business logic inside an enum since their job is just uniqueness and pretty much are inferior to classes in everything else.
public enum Role {
ROLE1 { public Actions getActions(){ return new Role1Actions() } },
ROLE2 { public Actions getActions(){ return new Role2Actions() } },
ROLE3 { public Actions getActions(){ return new Role3Actions() } };
}
I would make the Actions interface with as many method as types of operations can be executed per role
public interface Actions {
void action1();
// useful when there are more than 1 different actions per role
// even if only 1 now, there will be more in the future
vpod action2();
}
Then, just use the actions you can get from roles
user.getUserRole().action1();
user.getUserRole().action2();

You could do something like this, where all operations extend the Operation superclass and Role is an actual object instead of a string:
public abstract class Operation {
public void execute(User user) {
user.getRole().apply(this);
}
public abstract void operationForRole1();
public abstract void operationForRole2();
public abstract void operationForRole3();
}
public enum Role {
ROLE1 { public void apply(Operation op) { op.operationForRole1(); } },
ROLE2 { public void apply(Operation op) { op.operationForRole2(); } },
ROLE3 { public void apply(Operation op) { op.operationForRole3(); } };
public abstract void apply(Operation op);
}
Each Operation then implements the logic for various roles, and the client simply calls operation.execute(user). No if-else anywhere.

Related

How does State design pattern satisfy the open closed design principle

I recently just started learning design patterns using java and I was a bit confused and wondering how does state design pattern satisfy the open closed design principle as I couldn't online resource that has a concrete explanation on this..
I really like this book Head First Design Patterns. It has a lot of examples with super simple explanations!
Imagine you have a game where hero can be any person in the world. Let's call him as Hero.
He can run, swim and fly. You have a button where you can change its state or shape.
The code of Hero would look like this:
public class Hero
{
IState _state;
public Hero()
{
_state = new SpiderManState();
}
public void Run()
{
_state.Run();
}
public void Swim()
{
_state.Swim();
}
public void Fly()
{
_state.Fly();
}
public void ChangeShape()
{
_state = _state.ChangeChape();
}
}
Interfaces of IState would look like this:
public interface IState
{
void Run();
void Swim();
void Fly();
IState ChangeChape();
}
And concrete states look like this:
public class SpiderManState : IState
{
public void Fly()
{
Console.WriteLine("Spiderman is flying");
}
public void Run()
{
Console.WriteLine("Spiderman is running");
}
public void Swim()
{
Console.WriteLine("Spiderman is swimming");
}
public IState ChangeChape()
{
return new IronManState();
}
}
and IronManState would look like this:
public class IronManState : IState
{
public void Fly()
{
Console.WriteLine("IronMan is flying");
}
public void Run()
{
Console.WriteLine("IronMan is running");
}
public void Swim()
{
Console.WriteLine("IronMan is swimming");
}
public IState ChangeChape()
{
return new SpiderManState();
}
}
How does State design pattern satisfy the open closed design principle
Next time when you will want to add new State of Hero, you can add just new class like SomeSuperManState without editing Hero class.
So our Hero class is closed for modification, but it is opened for extension.
The state pattern is typically used as an extension of the strategy pattern that allows the strategy to be executed in steps or phases over multiple calls.
It implements the open/closed principle in the same way that the strategy pattern does.
Think of an executing workflow, which responds to events differently depending on the progress so far and which step is currently pending. When it receives an event, it dispatches it to the current step (the state), and the step takes action that can include changing the current step to one of the following ones.
The alternative to the state pattern is just implementing the whole strategy in a single object that stores internal state. The state pattern is used to divide up the responsibilities and allow the states to be implemented independently. It's also naturally emerges when the state must be persisted between calls.

OO programming issue - State Design Pattern

I have spent the last day trying to work out which pattern best fits my specific scenario and I have been tossing up between the State Pattern & Strategy pattern. When I read examples on the Internet it makes perfect sense... but it's another skill trying to actually apply it to your own problem. I will describe my scenario and the problem I am facing and hopefully someone can point me in the right direction.
Problem: I have a base object that has different synchronization states: i.e. Latest, Old, Never Published, Unpublished etc. Now depending on what state the object is in the behaviour is different, for example you cannot get the latest version for a base object that has never been published. At this point it seems the State design pattern is best suited... so I have implemented it and now each state has methods such as CanGetLatestVersion, GetLatestVersion, CanPublish, Publish etc.
It all seems good at this point. But lets say you have 10 different child objects that derive from the base class... my solution is broken because when the "publish" method is executed for each state it needs properties in the child object to actually carry out the operation but each state only has a reference to the base object. I have just spent some time creating a sample project illustrating my problem in C#.
public class BaseDocument
{
private IDocumentState _documentState;
public BaseDocument(IDocumentState documentState)
{
_documentState = documentState;
}
public bool CanGetLatestVersion()
{
return _documentState.CanGetLatestVersion(this);
}
public void GetLatestVersion()
{
if(CanGetLatestVersion())
_documentState.CanGetLatestVersion(this);
}
public bool CanPublish()
{
return _documentState.CanPublish(this);
}
public void Publish()
{
if (CanPublish())
_documentState.Publish(this);
}
internal void Change(IDocumentState documentState)
{
_documentState = documentState;
}
}
public class DocumentSubtype1 : BaseDocument
{
public string NeedThisData { get; set; }
}
public class DocumentSubtype2 : BaseDocument
{
public string NeedThisData1 { get; set; }
public string NeedThisData2 { get; set; }
}
public interface IDocumentState
{
bool CanGetLatestVersion(BaseDocument baseDocument);
void GetLatestVersion(BaseDocument baseDocument);
bool CanPublish(BaseDocument baseDocument);
bool Publish(BaseDocument baseDocument);
SynchronizationStatus Status { get; set; }
}
public class LatestState : IDocumentState
{
public bool CanGetLatestVersion(BaseDocument baseDocument)
{
return false;
}
public void GetLatestVersion(BaseDocument baseDocument)
{
throw new Exception();
}
public bool CanPublish(BaseDocument baseDocument)
{
return true;
}
public bool Publish(BaseDocument baseDocument)
{
//ISSUE HERE... I need to access the properties in the the DocumentSubtype1 or DocumentSubType2 class.
}
public SynchronizationStatus Status
{
get
{
return SynchronizationStatus.LatestState;
}
}
}
public enum SynchronizationStatus
{
NeverPublishedState,
LatestState,
OldState,
UnpublishedChangesState,
NoSynchronizationState
}
I then thought about implementing the state for each child object... which would work but I would need to create 50 classes i.e. (10 children x 5 different states) and that just seems absolute crazy... hence why I am here !
Any help would be greatly appreciated. If it is confusing please let me know so I can clarify!
Cheers
Let's rethink this, entirely.
1) You have a local 'Handle', to some data which you don't really own. (Some of it is stored, or published, elsewhere).
2) Maybe the Handle, is what we called the 'State' before -- a simple common API, without the implementation details.
3) Rather than 'CanPublish', 'GetLatestVersion' delegating from the BaseDocument to State -- it sounds like the Handle should delegate, to the specific DocumentStorage implementation.
4) When representing external States or Storage Locations, use of a separate object is ideal for encapsulating the New/Existent/Deletion state & identifier, in that storage location.
5) I'm not sure if 'Versions' is part of 'Published Location'; or if they're two independent storage locations. Our handle needs a 'Storage State' representation for each independent location, which it will store to/from.
For example:
Handle
- has 1 LocalCopy with states (LOADED, NOT_LOADED)
- has 1 PublicationLocation with Remote URL and states (NEW, EXIST, UPDATE, DELETE)
Handle.getVersions() then delegates to PublicationLocation.
Handle.getCurrent() loads a LocalCopy (cached), from PublicationLocation.
Handle.setCurrent() sets a LocalCopy and sets Publication state to UPDATE.
(or executes the update immediately, whichever.)
Remote Storage Locations/ Transports can be subtyped for different methods of accessing, or LocalCopy/ Document can be subtyped for different types of content.
THIS, I AM PRETTY SURE, IS THE MORE CORRECT SOLUTION.
[Previously] Keep 'State' somewhat separate from your 'Document' object (let's call it Document, since we need to call it something -- and you didn't specify.)
Build your heirarchy from BaseDocument down, have a BaseDocument.State member, and create the State objects with a reference to their Document instance -- so they have access to & can work with the details.
Essentially:
BaseDocument <--friend--> State
Document subtypes inherit from BaseDocument.
protected methods & members in Document heirarchy, enable State to do whatever it needs to.
Hope this helps.
Many design patterns can be used to this kind of architecture problem. It is unfortunate that you do not give the example of how you do the publish. However, I will state some of the good designs:
Put the additional parameters to the base document and make it
nullable. If not used in a document, then it is null. Otherwise, it
has value. You won't need inheritance here.
Do not put the Publish method to the DocumentState, put in the
BaseDocument instead. Logically, the Publish method must be part
of BaseDocument instead of the DocumentState.
Let other service class to handle the Publishing (publisher
service). You can achieve it by using abstract factory pattern. This
way, you need to create 1:1 document : publisher object. It may be
much, but you has a freedom to modify each document's publisher.
public interface IPublisher<T> where T : BaseDocument
{
bool Publish(T document);
}
public interface IPublisherFactory
{
bool Publish(BaseDocument document);
}
public class PublisherFactory : IPublisherFactory
{
public PublisherFactory(
IPublisher<BaseDocument> basePublisher
, IPublisher<SubDocument1> sub1Publisher)
{
this.sub1Publisher = sub1Publisher;
this.basePublisher = basePublisher;
}
IPublisher<BaseDocument> basePublisher;
IPublisher<SubDocument1> sub1Publisher;
public bool Publish(BaseDocument document)
{
if(document is SubDocument1)
{
return sub1Publisher.Publish((SubDocument1)document);
}
else if (document is BaseDocument)
{
return basePublisher.Publish(document);
}
return false;
}
}
public class LatestState : IDocumentState
{
public LatestState(IPublisherFactory factory)
{
this.factory = factory;
}
IPublisherFactory factory;
public bool Publish(BaseDocument baseDocument)
{
factory.Publish(baseDocument);
}
}
Use Composition over inheritance. You design each interface to each state, then compose it in the document. In summary, you can has 5 CanGetLatestVersion and other composition class, but 10 publisher composition class.
More advancedly and based on the repository you use, maybe you can use Visitor pattern. This way, you can has a freedom to modify each publishing methods. It is similiar to my point 3, except it being declared in one class. For example:
public class BaseDocument
{
}
public class SubDocument1 : BaseDocument
{
}
public class DocumentPublisher
{
public void Publish(BaseDocument document)
{
}
public void Publish(SubDocument1 document)
{
// do the prerequisite
Publish((BaseDocument)document);
// do the postrequisite
}
}
There may be other designs available but it is dependent to how you access your repository.

design pattern query

i have a question regarding design patterns.
suppose i want to design pig killing factory
so the ways will be
1) catch pig
2)clean pig
3) kill pig
now since these pigs are supplied to me by a truck driver
now if want to design an application how should i proceed
what i have done is
public class killer{
private Pig pig ;
public void catchPig(){ //do something };
public void cleanPig(){ };
public void killPig(){};
}
now iam thing since i know that the steps will be called in catchPig--->cleanPig---->KillPig manner so i should have an abstract class containing these methods and an execute method calling all these 3 methods.
but i can not have instance of abstract class so i am confused how to implement this.
remenber i have to execute this process for all the pigs that comes in truck.
so my question is what design should i select and which design pattern is best to solve such problems .
I would suggest a different approach than what was suggested here before.
I would do something like this:
public abstract class Killer {
protected Pig pig;
protected abstract void catchPig();
protected abstract void cleanPig();
protected abstract void killPig();
public void executeKillPig {
catchPig();
cleanPig();
killPig();
}
}
Each kill will extend Killer class and will have to implement the abstract methods. The executeKillPig() is the same for every sub-class and will always be performed in the order you wanted catch->clean->kill. The abstract methods are protected because they're the inner implementation of the public executeKillPig.
This extends Avi's answer and addresses the comments.
The points of the code:
abstract base class to emphasize IS A relationships
Template pattern to ensure the steps are in the right order
Strategy Pattern - an abstract class is as much a interface (little "i") as much as a Interface (capital "I") is.
Extend the base and not use an interface.
No coupling of concrete classes. Coupling is not an issue of abstract vs interface but rather good design.
public abstract Animal {
public abstract bool Escape(){}
public abstract string SaySomething(){}
}
public Wabbit : Animal {
public override bool Escape() {//wabbit hopping frantically }
public override string SaySomething() { return #"What's Up Doc?"; }
}
public abstract class Killer {
protected Animal food;
protected abstract void Catch(){}
protected abstract void Kill(){}
protected abstract void Clean(){}
protected abstract string Lure(){}
// this method defines the process: the methods and the order of
// those calls. Exactly how to do each individual step is left up to sub classes.
// Even if you define a "PigKiller" interface we need this method
// ** in the base class ** to make sure all Killer's do it right.
// This method is the template (pattern) for subclasses.
protected void FeedTheFamily(Animal somethingTasty) {
food = somethingTasty;
Catch();
Kill();
Clean();
}
}
public class WabbitHunter : Killer {
protected override Catch() { //wabbit catching technique }
protected override Kill() { //wabbit killing technique }
protected override Clean() { //wabbit cleaning technique }
protected override Lure() { return "Come here you wascuhwy wabbit!"; }
}
// client code ********************
public class AHuntingWeWillGo {
Killer hunter;
Animal prey;
public AHuntingWeWillGo (Killer aHunter, Animal aAnimal) {
hunter = aHunter;
prey = aAnimal;
}
public void Hunt() {
if ( !prey.Escape() ) hunter.FeedTheFamily(prey)
}
}
public static void main () {
// look, ma! no coupling. Because we pass in our objects vice
// new them up inside the using classes
Killer ElmerFudd = new WabbitHunter();
Animal BugsBunny = new Wabbit();
AHuntingWeWillGo safari = new AHuntingWeWillGo( ElmerFudd, BugsBunny );
safari.Hunt();
}
The problem you are facing refer to part of OOP called polymorphism
Instead of abstract class i will be using a interface, the difference between interface an abstract class is that interface have only method descriptors, a abstract class can have also method with implementation.
public interface InterfaceOfPigKiller {
void catchPig();
void cleanPig();
void killPig();
}
In the abstract class we implement two of three available methods, because we assume that those operation are common for every future type that will inherit form our class.
public abstract class AbstractPigKiller implements InterfaceOfPigKiller{
private Ping pig;
public void catchPig() {
//the logic of catching pigs.
}
public void cleanPig() {
// the logic of pig cleaning.
}
}
Now we will create two new classes:
AnimalKiller - The person responsible for pig death.
AnimalSaver - The person responsible for pig release.
public class AnimalKiller extends AbstractPigKiller {
public void killPig() {
// The killing operation
}
}
public class AnimalSaver extends AbstractPigKiller {
public void killPing() {
// The operation that will make pig free
}
}
As we have our structure lets see how it will work.
First the method that will execute the sequence:
public void doTheRequiredOperation(InterfaceOfPigKiller killer) {
killer.catchPig();
killer.cleanPig();
killer.killPig();
}
As we see in the parameter we do not use class AnimalKiller or AnimalSever. Instead of that we have the interface. Thank to this operation we can operate on any class that implement used interface.
Example 1:
public void test() {
AnimalKiller aKiller = new AnimalKiller();// We create new instance of class AnimalKiller and assign to variable aKiller with is type of `AnimalKilleraKiller `
AnimalSaver aSaver = new AnimalSaver(); //
doTheRequiredOperation(aKiller);
doTheRequiredOperation(aSaver);
}
Example 2:
public void test() {
InterfaceOfPigKiller aKiller = new AnimalKiller();// We create new instance of class AnimalKiller and assign to variable aKiller with is type of `InterfaceOfPigKiller `
InterfaceOfPigKiller aSaver = new AnimalSaver(); //
doTheRequiredOperation(aKiller);
doTheRequiredOperation(aSaver);
}
The code example 1 and 2 are equally in scope of method doTheRequiredOperation. The difference is that in we assign once type to type and in the second we assign type to interface.
Conclusion
We can not create new object of abstract class or interface but we can assign object to interface or class type.

Refactoring Switching On Types Code Smell When Adding Method to Type Seems Inappropriate

Let's say I have the following method that, given a PaymentType, sends an appropriate payment request to each facility from which the payment needs to be withdrawn:
public void SendRequestToPaymentFacility(PaymentType payment) {
if(payment is CreditCard) {
SendRequestToCreditCardProcessingCenter();
} else if(payment is BankAccount) {
SendRequestToBank();
} else if(payment is PawnTicket) {
SendRequestToPawnShop();
}
}
Obviously this is a code smell, but when looking for an appropriate refactoring, the only examples I have seen involve cases where the code executed within the conditionals are clearly the responsibility of the class itself, e.g. with the standard example given:
public double GetArea(Shape shape) {
if(shape is Circle) {
Circle circle = shape As Circle;
return circle.PI * (circle.radius * circle.radius);
} else if(shape is Square) {
Square square = shape as Square;
return square.length * square.width;
}
}
GetArea() seems like a pretty reasonable responsibility for each Shape subclass, and can of course be refactored nicely:
public class Shape
{
/* ... */
public abstract double GetArea();
}
public class Circle
{
public override double GetArea()
{
return PI * (radius * radius);
}
}
However, SendRequestToPaymentFacility() does not seem like an appropriate responsibility for a PaymentType to have. (and would seem to violate the Single Responsibility Principle). And yet I need to send a request to an appropriate PaymentFacility based on the type of PaymentType - what is the best way to do this?
You could consider adding a property or method to your CandyBar class which indicates whether or not the CandyBar contains nuts. Now your GetProcessingPlant() method does not have to have knowledge of the different types of CandyBars.
public ProcessingPlant GetProcessingPlant(CandyBar candyBar) {
if(candyBar.ContainsNuts) {
return new NutProcessingPlant();
} else {
return new RegularProcessingPlant();
}
}
One option would be to add an IPaymentFacility interface parameter to the constructors for the individual PaymentType descendants. The base PaymentType could have an abstract PaymentFacility property; SendRequestToPaymentFacility on the base type would delegate:
public abstract class PaymentType
{
protected abstract IPaymentFacility PaymentFacility { get; }
public void SendRequestToPaymentFacility()
{
PaymentFacility.Process(this);
}
}
public interface IPaymentFacility
{
void Process(PaymentType paymentType);
}
public class BankAccount : PaymentType
{
public BankAccount(IPaymentFacility paymentFacility)
{
_paymentFacility = paymentFacility;
}
protected override IPaymentFacility PaymentFacility
{
get { return _paymentFacility; }
}
private readonly IPaymentFacility _paymentFacility;
}
Rather than wiring up the dependency injection manually, you could use a DI/IoC Container library. Configure it so that a BankAccount got a Bank, etc.
The downside is that the payment facilities would only have access to the public (or possibly internal) members of the base-class PaymentType.
Edit:
You can actually get at the descendant class members by using generics. Either make SendRequestToPaymentFacility abstract (getting rid of the abstract property), or get fancy:
public abstract class PaymentType<TPaymentType>
where TPaymentType : PaymentType<TPaymentType>
{
protected abstract IPaymentFacility<TPaymentType> PaymentFacility { get; }
public void SendRequestToPaymentFacility()
{
PaymentFacility.Process((TPaymentType) this);
}
}
public class BankAccount : PaymentType<BankAccount>
{
public BankAccount(IPaymentFacility<BankAccount> paymentFacility)
{
_paymentFacility = paymentFacility;
}
protected override IPaymentFacility<BankAccount> PaymentFacility
{
get { return _paymentFacility; }
}
private readonly IPaymentFacility<BankAccount> _paymentFacility;
}
public interface IPaymentFacility<TPaymentType>
where TPaymentType : PaymentType<TPaymentType>
{
void Process(TPaymentType paymentType);
}
public class Bank : IPaymentFacility<BankAccount>
{
public void Process(BankAccount paymentType)
{
}
}
The downside here is coupling the Bank to the BankAccount class.
Also, Eric Lippert discourages this, and he makes some excellent points.
One approach you can take here is to use the Command pattern. In this case, you would create and queue up the appropriate command (e.g. Credit Card, Bank Account, Pawn Ticket) rather than calling a particular method. Then you could have separate command processors for each command that would take the appropriate action.
If you don't want the conditional complexity here, you could raise a single type of command that included the payment type as a property, and then a command processor could be responsible for figuring out how to handle that request (with the appropriate payment processor).
Either of these could help your class follow Single Responsibility Principle by moving details of payment processing out of it.

Ninject, Generic Referential Bindings

I think this falls under the concept of contextual binding, but the Ninject documentation, while very thorough, does not have any examples close enough to my current situation for me to really be certain. I'm still pretty confused.
I basically have classes that represent parameter structures for queries. For instance..
class CurrentUser {
string Email { get; set; }
}
And then an interface that represents its database retrieval (in the data layer)
class CurrentUserQuery : IQueryFor<CurrentUser> {
public CurrentUserQuery(ISession session) {
this.session = session;
}
public Member ExecuteQuery(CurrentUser parameters) {
var member = session.Query<Member>().Where(n => n.Email == CurrentUser.Email);
// validation logic
return member;
}
}
Now then, what I want to do is to establish a simple class that can take a given object and from it get the IQueryFor<T> class, construct it from my Ninject.IKernel (constructor parameter), and perform the ExecuteQuery method on it, passing through the given object.
The only way I have been able to do this was to basically do the following...
Bind<IQueryFor<CurrentUser>>().To<CurrentUserQuery>();
This solves the problem for that one query. But I anticipate there will be a great number of queries... so this method will become not only tedious, but also very prone to redundancy.
I was wondering if there is an inherit way in Ninject to incorporate this kind of behavior.
:-
In the end, my (ideal) way of using this would be ...
class HomeController : Controller {
public HomeController(ITransit transit) {
// injection of the transit service
}
public ActionResult CurrentMember() {
var member = transit.Send(new CurrentUser{ Email = User.Identity.Name });
}
}
Obviously that's not going to work right, since the Send method has no way of knowing the return type.
I've been dissecting Rhino Service Bus extensively and project Alexandria to try and make my light, light, lightweight implementation.
Update
I have been able to get a fairly desired result using .NET 4.0 dynamic objects, such as the following...
dynamic Send<T>(object message);
And then declaring my interface...
public interface IQueryFor<T,K>
{
K Execute(T message);
}
And then its use ...
public class TestCurrentMember
{
public string Email { get; set; }
}
public class TestCurrentMemberQuery : IConsumerFor<TestCurrentMember, Member>
{
private readonly ISession session;
public TestCurrentMemberQuery(ISession session) {
this.session = session;
}
public Member Execute(TestCurrentMember user)
{
// query the session for the current member
var member = session.Query<Member>()
.Where(n => n.Email == user.Email).SingleOrDefault();
return member;
}
}
And then in my Controller...
var member = Transit.Send<TestCurrentMemberQuery>(
new TestCurrentMember {
Email = User.Identity.Name
}
);
effectively using the <T> as my 'Hey, This is what implements the query parameters!'. It does work, but I feel pretty uncomfortable with it. Is this an inappropriate use of the dynamic function of .NET 4.0? Or is this more the reason why it exists in the first place?
Update (2)
For the sake of consistency and keeping this post relative to just the initial question, I'm opening up a different question for the dynamic issue.
Yes, you should be able to handle this with Ninject Conventions. I am just learning the Conventions part of Ninject, and the documentation is sparse; however, the source code for the Conventions extension is quite light and easy to read/navigate, also Remo Gloor is very helpful both here and on the mailing list.
The first thing I would try is a GenericBindingGenerator (changing the filters and scope as needed for your application):
internal class YourModule : NinjectModule
{
public override void Load()
{
Kernel.Scan(a => {
a.From(System.Reflection.Assembly.GetExecutingAssembly());
a.InTransientScope();
a.BindWith(new GenericBindingGenerator(typeof(IQueryFor<>)));
});
}
}
The heart of any BindingGenerator is this interface:
public interface IBindingGenerator
{
void Process(Type type, Func<IContext, object> scopeCallback, IKernel kernel);
}
The Default Binding Generator simply checks if the name of the class matches the name of the interface:
public void Process(Type type, Func<IContext, object> scopeCallback, IKernel kernel)
{
if (!type.IsInterface && !type.IsAbstract)
{
Type service = type.GetInterface("I" + type.Name, false);
if (service != null)
{
kernel.Bind(service).To(type).InScope(scopeCallback);
}
}
}
The GenericBindingGenerator takes a type as a constructor argument, and checks interfaces on classes scanned to see if the Generic definitions of those interfaces match the type passed into the constructor:
public GenericBindingGenerator(Type contractType)
{
if (!contractType.IsGenericType && !contractType.ContainsGenericParameters)
{
throw new ArgumentException("The contract must be an open generic type.", "contractType");
}
this._contractType = contractType;
}
public void Process(Type type, Func<IContext, object> scopeCallback, IKernel kernel)
{
Type service = this.ResolveClosingInterface(type);
if (service != null)
{
kernel.Bind(service).To(type).InScope(scopeCallback);
}
}
public Type ResolveClosingInterface(Type targetType)
{
if (!targetType.IsInterface && !targetType.IsAbstract)
{
do
{
foreach (Type type in targetType.GetInterfaces())
{
if (type.IsGenericType && (type.GetGenericTypeDefinition() == this._contractType))
{
return type;
}
}
targetType = targetType.BaseType;
}
while (targetType != TypeOfObject);
}
return null;
}
So, when the Conventions extension scans the class CurrentUserQuery it will see the interface IQueryFor<CurrentUser>. The generic definition of that interface is IQueryFor<>, so it will match and that type should get registered for that interface.
Lastly, there is a RegexBindingGenerator. It tries to match interfaces of the classes scanned to a Regex given as a constructor argument. If you want to see the details of how that operates, you should be able to peruse the source code for it now.
Also, you should be able to write any implementation of IBindingGenerator that you may need, as the contract is quite simple.