There seems to be a conflict in the layoff announcement - all technology roadmaps remain intact
vs. We have re-established Nuremburg as the headquarters of our SUSE business unit and the prioritization and resourcing of certain development efforts - including Mono - will now be determined by the business unit leaders there.
(citation of Attachmate Group CEO)
Miguel de Icaza stated in his twitter account that: I'll have a blog post next Monday, I am tied up until then
.
I would suggest waiting for the next Monday and check what comes out at [http://tirania.org/blog/]3.
UPDATE:
On Monday Miguel de Icaza announced that he and former members of the Mono team founded a new startup called Xamarin that will:
- Build a new commercial .NET offering for iOS
- Build a new commercial .NET offering for Android
- Continue to contribute, maintain and develop the open source Mono and Moonlight components.
- Explore the Moonlight opportunities in the mobile space and the Mac appstore.
They seems to plan to deliver a MonoTouch replacement. First version is expected to be available in 3-4 months time frame (Q3 2011).
Source: http://tirania.org/blog/archive/2011/May-16.html
UPDATE 2011-07-18:
Xamarin obtained a perpetual license to all the intellectual property of Mono, MonoTouch, Mono for Android, Mono for Visual Studio and will continue updating and selling those products.
Source: http://tirania.org/blog/archive/2011/Jul-18.html
If you have too many dependencies being passed around, the general technique is to eliminate those dependencies higher up in the call stack, by changing the order decisions are made. This is easiest to explain with an example:
getPath(config, user) {
if (config.isB2B())
return b2bpath(config, user);
else
return b2cpath(config, user);
}
b2bpath(config, user) {
if (!config.allowedToAccessPath(user))
return accessDeniedPage();
else
return "My fancy b2b page";
}
b2cpath(config, user) {
if (!config.allowedToAccessPath(user))
return accessDeniedPage();
else
return "My fancy b2c page";
}
You are repeating the authorization check down at the lowest levels of the call stack, so move it up:
getPath(config, user) {
if (!config.allowedToAccessPath(user))
return accessDeniedPage();
if (config.isB2B())
return b2bpath();
else
return b2cpath();
}
b2bpath() {
return "My fancy b2b page";
}
b2cpath() {
return "My fancy b2c page";
}
Then repeat to see if you can move some of the decisions into the code that calls getPath
. This is a simple example, but I see the former kind of code all over the place with more layers. Start with decisions at your lowest layers, and try to figure out ways to move them up. Sometimes this requires judicious use of inheritance, like:
getPath(config, user) {
module = config.isB2B() ? B2BModule() : B2CModule()
if (!config.allowedToAccessPath(user))
return module.accessDeniedPage();
return module.getPath();
}
It's very rare not to be able to simplify dependencies this way. It's a matter of trying different arrangements until you find one that works.
If you have workflow-type dependencies, not just data dependencies, as in your first example, you can separate them out using something like this:
step1 = new ValidateHeaderId(inputHeaderId);
step2 = new FindShipment(retShipmentRepository);
step3 = new ValidateUserPermission(user, inputPostCode, inputEmail);
step4 = new SaveReturnOrder(inputLines, inputReference);
step5 = new CheckSaveStatus();
notSet = new NotSetPage(templateEngine, searchPage);
notPermitted = new NotPermittedPage(templateEngine, searchPage);
saveErrors = new SaveErrorsPage();
success = new SuccessPage();
requestTokenConfirmation = new RequestTokenConfirmation();
steps = [step1, [notSet, step2], [notSet, step3], [notPermitted, step4],
[saveErrors, step5], [success, requestTokenConfirmation]];
executeSteps(steps);
This recognizes you have a series of steps which each produce some sort of result and choose the next step. executeSteps
abstracts away the repetition of calling run()
on each step, and passing the output from the previous step into the next step. This allows the steps to be stored in a data structure instead of a function, which can then be built up in several different ways, including by some sort of registration process or config file. Once each step object has been created, its dependencies no longer need to be tracked outside it. I believe the rules engines from BobDalgleish's answer are basically pre-existing libraries to help you do this more easily.
Best Answer
Ninject provides the concept of a module to allow you to group related bindings into a single class.
https://github.com/ninject/Ninject/wiki/Modules-and-the-Kernel