How to use my own MainWindow with Caliburn.Micro? - caliburn.micro

A similar question is asked here but CM has changed and the solution provided to that question is not supported anymore.
The solution to the question mentioned above was to write your own Bootstrapper<TRootView> derived class. But the generic version of Bootstrapper is not there in the latest version.
What is the alternate ?
I have the following folder hierarchy in project
Project
|-Modules
|-MainWindow
|-ViewModels
|- MainWindowViewModel
|-Views
|- MainWindow.xaml
Here is my OnStartup override
protected override void OnStartup(object sender, System.Windows.StartupEventArgs e)
{
DisplayRootViewFor<MainWindowViewModel>();
}

your bootstrapper now inherits BootstrapperBase, then you use
DisplayRootViewFor<T>
then depending on your flavor of view-first / viewmodel-first development. Usually done in the OnStartUp override.
Edit:
Glad you figured it out...

Related

Bundle /service override chain in Symfony2?

Is there a possibility to construct bundle override chains in Symfony2?
For example, there is a CoreFeatureX in the product core. And there are two plugins extending that feature PluginA and PluginB.
Using standard methods from here or from here plugins can override CoreFeatureX no problem. But only one of them at a time can currently do that.
Is there a possibility to automatically construct override chains so that if both PluginA and PluginB registered in the system, they can both extend CoreFeatureX (may be, by inheriting from each other automatically) but be unaware of each other?
Similiar extension technology is used by XenForo forum system, for example. XenForo constructs an inheritance chain from plugins, that were registered as some core class extensions. It then exposes the topmost class of the extension chain as that core class itself.
Since Symfony2 doesn't let us to extend the same bundle twice at the same time, you can't to that in "clean" Symfony2.
This is clearly implemented in Symfony\Component\HttpKernel\Kernel::initializeBundles() here:
protected function initializeBundles()
{
// (...)
foreach ($this->registerBundles() as $bundle) {
//(...)
if ($parentName = $bundle->getParent()) {
if (isset($directChildren[$parentName])) {
throw new \LogicException(sprintf('Bundle "%s" is directly extended by two bundles "%s" and "%s".', $parentName, $name, $directChildren[$parentName]));
}
//(...)
$directChildren[$parentName] = $name;
} else {
$topMostBundles[$name] = $bundle;
}
}
//(...)
}
I guess this is for a reason. Anyway you could try to override Kernel class behavior of initializeBundles method (in AppKernel class). In the line where exception above if thrown, you could change parent bundle from CoreFeatureX to the last in chain.
In case of PluginB change parent bundle to PluginA because it already extends CoreFeatureX.
In case of PluginC change parent bundle to PluginB because it is on the end of current inheritance chain.
I don't know if it could work, it's just an idea. Anyway that would be an interesting experiment. ;-)
Edit.
I just notined in your comment to the question that you wrote:
But the requirement is for both PluginA and PluginB to extend
CoreFeatureX and to be unaware of each other.
Well there's something wrong here. How do you want to override one plugin by the second and on the other side make them unaware of each other? Doesn't make sense for me.

Sylius how to override the CoreBundle Checkout process

I'm working on a project and I'd like to ask for a clean/best way to override the steps in the
Sylius\Bundle\CoreBundle\Checkout\CheckoutProcessScenario
I'd like to preserve the custom mechanics of the whole process just add a custom step at the end and remove the finalize step.
$builder
->add('security', 'sylius_checkout_security')
->add('addressing', 'sylius_checkout_addressing')
->add('shipping', 'sylius_checkout_shipping')
->add('finalize', 'sylius_checkout_finalize')
->add('payment', 'sylius_checkout_payment')
->add('purchase', 'sylius_checkout_purchase')
;
What's the best form of doing so? If it's extending the bundle and overwriting it I'd like some help with that of at least some information to point me in the right direction - currently I'm not getting any results on my own.
I've read the docs on the bundle itself but it doesn't explain how to override the built in process.
I've also read the symfony cookbook on extending resources:
http://symfony.com/doc/2.0/cookbook/bundles/inheritance.html#overriding-resources-templates-routing-translations-validation-etc
and:
http://symfony.com/doc/current/cookbook/bundles/override.html
If anyone has some experience on the topic and would like to share thier insights I'd be very gratefull. Thanks in advance.
You could change the service class to a custom one.
You can overwrite the parameter sylius.checkout_scenario.class.
app/config/config.yml:
<parameter key="sylius.checkout_scenario.class">
Your\Class
</parameter>
I've done it a bit different but still the point was good :)
What I've done is use the service compiler to override it with my own class and override the original file. The basics are explained here:
http://symfony.com/doc/current/cookbook/bundles/override.html
in the Services & Configuration section :)
Then I just had to include the compiler pass
// src/Acme/ShopBundle/AcmeShopBundle.php
namespace Acme\ShopBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Acme\ShopBundle\DependencyInjection\Compiler\CustomCompilerPass;
class AcmeMailerBundle extends Bundle
{
public function build(ContainerBuilder $container)
{
parent::build($container);
$container->addCompilerPass(new CustomCompilerPass());
}
}
Inside the compiler pass I just extended the base file and overwrote the function I needed. Droppin it by in case anyone needs to pointed in the right direction.

Is EventAggregator.PublishOnUIThread(aMessage) the same as EventAggregator.Publish(aMessage,Execute.OnUIThread)?

Micro 2.x users,
I'm having trouble mocking (using moq) and verifying a call to EventAggregator.PublishOnUIThread since it is a extension method!
Poking around in the source code made me come up with another method call that IS mockable :-)
But it would be nice to know if EventAggregator.Publish(aMessage,Execute.OnUIThread)
is the equivalent of EventAggregator.PublishOnUIThread(aMessage)?
Yes, they are equivalent.
This is how the EventAggregator.PublishOnUIThread extension method is currently implemented:
public static void PublishOnUIThread(this IEventAggregator eventAggregator, object message)
{
eventAggregator.Publish(message, Execute.OnUIThread);
}
For details, see the EventAggregatorExtensions.cs source code.

Overriding page_list controller inside a package in Concrete5.6.1.2

Is there a way to override the controller file located at /concrete/blocks/page_list/controller.php and place it inside /packages/mypackage/blocks/page_list/? I'd like to make some changes to the original edit and view.
In /packages/mypackage/blocks/page_list/controller.php, I tried doing this but it does not seem to have any effect:
class PageListBlockController extends Concrete5_Controller_Block_PageList { ... }
You can now override/extend core classes via packages in newer versions Concrete5 (v.5.6+).
You must add to your package's main controller.php file:
public function on_start(){
$objEnv = Environment::get();
$objEnv->overrideCoreByPackage('blocks/page_list/controller.php', $this);
}
You don't have to copy over the whole core controller, just declare your new block controller like this:
class PageList extends Concrete5_Controller_Block_Page_List {
public function mymethod() {
}
}
(what class you're extending and where you put the file may vary depending on your C5 version - just compare the /concrete/ folder structure and files for reference)
The following C5 forum posts may be of help:
Overriding Core Class with Package
Can A Package Override A Core Library?
A caution, though - if you're hoping to submit to the official C5 marketplace, they generally don't accept Add-Ons with overrides.
No. You can't override a block controller from within a package. Just imagine if more than one package did this. (You can, however, have a block template within your package directory, but this makes sense because it adds rather than replaces.)
If you can, you should override by putting it in /blocks/page_list/controller.php.
However, if you still need to override it from you package, you should look into the not-very-well-supported Environment::overrideCoreByPackage() and try:
Environment::get()->overrideCoreByPackage('/blocks/page_list/controller.php', $myPackage);
See the source:
https://github.com/concrete5/concrete5/blob/master/web/concrete/core/libraries/environment.php#L123
And an example of usage:
http://www.concrete5.org/community/forums/customizing_c5/override-a-core-class-within-a-package/#460765

Is it right to instantiate active classes outside of Page_Load?

a quick question for an ASP.NET expert. It is an arguable moment for us in the company at the moment...
We have built a nice (no bugs in there) CMS framework that we use for our sites...
It goes something like this:
MyCms.Content.Channels channels = new MyCms.Content.Channels();
where at the moment of instantiating the Channels class, it loads a bunch of XML files and converts them to a List<MyCms.Content.Channels.Channel> that is held within the Channels class, and cached using System.Web.HttpRuntime.Cache (until there are any changes to the folder holding the XML files)
The Channels class is basically a hierarchical structure for web pages...
We normally use it like this in our ASP.NET pages (code behind):
public partial class Default : System.Web.UI.Page
{
public MyCms.Content.Channels channels;
public MyCms.Content.Images images;
public MyCms.Content.Channels.Channel CurrentChannel;
public List<MyCms.Content.Channels.Channel> latestItems;
public MyCms.Content.GameVotes votes;
public MyCms.Content.GameVotes.Vote vote;
protected void Page_Load(object sender, EventArgs e)
{
channels = new MyCms.Content.Channels();
images = new MyCms.Content.Images();
..
}
as you can see, the public variable 'channels' is instantiated at Page_Load()... where at the moment it has loaded a bunch of XML files either from a file system, or from cache...
Our colleague though, is sometimes instantiating this class outside of Page_Load() - right next to the public declaration of the 'channels' variable like this:
public partial class Default : System.Web.UI.Page
{
public MyCms.Content.Channels channels = new MyCms.Content.Channels();
protected void Page_Load(object sender, EventArgs e)
{
... he does the same in various User Controls...
Now thing is.. I need your opinion on whether it's ok to instantiate a very active class like this - outside of Page_Load() event... ? The site that was built by our colleague was hanging the entire IIS from time to time, and I just suspect that this could be one reason... - what do you think, please ? :)
The same CMS Framework is being used on other sites, on other servers with no issues at all... So the only difference I could find between the good working sites and the one that is hanging - is this .. instantiation of 'channels' class outside the scope of Page_Load()...
It shouldn't make a difference. That's not to say it doesn't.
All that's happening is you're changing the point at which you create the object from load event, which happens about half way through the lifecycle to the constructor, right at the very start. At both points the cache should be available as it's part of the context, although you really ought to check that.
I would say though, instantiating such an important class should happen at a specific point, like page initialise or load, rather than at constructor.
Simon
The only difference I'm aware of is that if you initialize the objects outside of the Page_Load they will be created as soon as your page's class is created (i.e. before all the Page_XXX events), and if you initialize them inside the Page_Load they will be created only when the event is called.
That means if your application crashes, redirects or for whatever reason does not enter Page_Load, you have created the object uselessly.

Resources