One of my team members decided to use autofac on one of our services and because we wanted to try it out we stuck with it.
Now some time has passed and the container setup method has grown! It so big that we are having problems with it.
Splitting it up did not bring the results we looked for. Maybe we are just using it wrong.
So my question is: How can we manage the container setup? Can we dump into XML or are there any other best practices?
There are many ways to manage container setup with autofac.
One of the most common ways is to use a Module and register it with the builder. You can break up multiple groups of registration this way:
public class DALModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.Register<SomeDataSomething>().As<IDataSomething>();
builder.Register<SomeOtherSomething( c => SomeOtherSomething.Create());
//and so on
}
}
Then register these broken up modules with the builder either via code or XML.
(a simple call to builder.RegisterModule( new DALModule()) would do it here). See the wiki page on Structuring with Modules.
Or, you can use only XML files (or use XML and modules together). See the wiki page on XML config for this.
Related
I need to extend spring data in order to support my own custom backend. From the spring data website, it seems that it is possible to add community modules to the framework, which in turn enables you to support a custom backend. However, I can't seem to find some code examples/docs illustrating the module implementation mechanism.
Even a basic example using a file-based persistence would be very helpful.
You just have to extend it then you can override the methods and add your own. If you're using IntelliJ, just implement/extend (for example) CrudRepository, execute Generate Code and select Implement methods or Override methods.
public MyRepository extends CrudRepository<T, Long>{
//in Mac, you press command + N. Then select Override methods.
//in Windows, I don't think Generate Method is given a shortcut. You can find it in the menu bar
}
Please also suggest which namespace to use. I am new to zend and MVC.
module.php
public function getServiceConfig()
{
// what code here?
}
**Album\Model\Album.php**
{
//what code here?
}
**Album\Model\AlbumTable.php**
{
//what code here?
//do we have to use this class or a different class?
}
I can understand the sudden confusion when starting out with ZF2. However, the manual has really done a good job at helping those who are just starting out. You can find the most up-to-date information here : http://zf2.readthedocs.org/en/latest/user-guide/overview.html
Once you've got the Skeleton Application working I believe some of your confusion will be relieved. If not, come back and ask more specific questions OR you could even join the FreeNode IRC channel at #zftalk.
But to also help answer some of what you've asked here:
getServiceConfig() is where you will interact with the ServiceManager. Try to stay away from closures and work with Factories.
Album.php is sort of like the Hydrator. You don't have to use a Hydrator but for example purposes it was put here. It can make like easier in the long run.
AlbumTable.php is the Database Table you will be interacting with.
The namespace which is used in the tutorial is called Album. The Skeleton application comes packaged with a namespace called Application to start with.
You can manually download ZF2 here: https://packages.zendframework.com/
The latest skeleton application can be found here: https://github.com/zendframework/ZendSkeletonApplication
You may also choose to use Composer to install your entire application which tends to make the installation process much easier for those just starting out, so in your situation I'm going to recommend you use that. You can find instructions on how to use Composer here: http://zf2.readthedocs.org/en/latest/user-guide/skeleton-application.html
I'm giving a MVVMCross a spin, to see if it will be of use in some bigger projects coming up, and it's great. I like the navigation, viewModel location and general cross-platform approach, which is just what I need. However, I'm a bit stuck on splitting out some of the dependency injection depending on the platform.
So, we have the basic application, with a shared portable library, that initialises the service references when starting up:
public TwitterSearchApp()
{
InitaliseServices();
}
private void InitaliseServices()
{
this.RegisterServiceInstance<ITwitterSearchProvider>(new TwitterSearchProvider());
}
Fine. That defines the service implementations that will be used across all the platforms. But what about the situation where I will need different implementations on different platforms - for instance perhaps storage/caching, where the core requirement is the same, but needs to be handled differently on a phone than on a tablet.
I thought it might go in Setup somewhere:
public class Setup : MvxBaseWinRTSetup
{
public Setup(Frame rootFrame): base(rootFrame)
{
}
protected override MvxApplication CreateApp()
{
var app = new TwitterSearchApp();//set platorm specific IoC here maybe?
return app;
}
protected override void AddPluginsLoaders(Cirrious.MvvmCross.Platform.MvxLoaderPluginRegistry loaders)
{ // or perhaps here?
loaders.AddConventionalPlugin<Cirrious.MvvmCross.Plugins.Visibility.WinRT.Plugin>();
base.AddPluginsLoaders(loaders);
}
}
but I'm not sure. I've seen the references to replacing the ViewModel locator, but is there are similar way of replacing the other IoC services?
thanks, great job on the framework in general, I really like how it works (apart from this bit, which I don't understand properly yet)
Toby
There are three basic options:
1. Add the platform specific services in your UI project and then register them in an override during setup - which override you use depends on when your services are needed, but for most cases you can just use the InitializeLastChance override which gets called at the end of initialization:
protected override void InitializeLastChance()
{
this.RegisterServiceInstance<IMyService>(new SingletonMyService());
this.RegisterServiceType<IMyService2, PerCallService2>();
base.InitialiseLastChance();
}
If 'last chance' is too late for your service - if you need the service during the core app startup - then you can override any initialisation step after InitializeIoC - e.g. InitializeFirstChance. For the list and order of initialisation steps, see InitializePrimary and InitializeSecondary in MvxBaseSetup.cs
2. Add the platform specific registration in some other bit of the UI code - e.g. in the constructor for a specific View (this option isn't used much... but you could use it in some odd cases, if you wanted to...)
3. Use a plugin - all plugins are is a wrapper around IoC. Plugins have the disadvantage that they add some development overhead (you have to add the separate projects and the plugin boilerplate files), but they have the advantages that they can be reused across apps and it's easier to write test apps and test harnesses for them. For more info on plugins, see Making mono cross platform support for Task/Intent and see http://slodge.blogspot.co.uk/2012/10/build-new-plugin-for-mvvmcrosss.html
My general advice - start with the first option and migrate out to a plugin if you want to reuse the code in later projects...
What is the proper way to do that?
Let's say we have some third party library in our project and we need to provide an access to some controls which are sealed.
New widgets will be created and added to the application using MEF and they should be able to import some controls from the core application.
So how to export those controls properly?
If you cannot modify the original class (e.g. ThirdPartyComponent), then you can do the export via a property on another class (e.g. ThirdPartyComponentExporter):
public class ThirdPartyComponentExporter
{
[Export(typeof(ThirdPartyComponent))]
public ThirdPartyComponent Foo
{
get
{
return new ThirdPartyComponent();
}
}
}
For visual controls, you may have to use CreationPolicy.NonShared to prevent MEF from reusing the same instance in different locations.
What about wrapping the third party controls in "export" classes and then access this control through the wrapper?
I've divided my GWT app into multiple modules, what's the best way to navigate between them?
Currently I'm using Window.Location.assign("foo.html#bar") but is there a better way?
History.newItem only works for history within the current module. To change to another page I think the best way is to use Window.Location.assign.
I don't fully remember the issue (and perhaps it has been fixed now), but in our application we stopped using relative URLs as they would sometimes break (we have a comment referencing http://groups.google.com/group/Google-Web-Toolkit/browse_thread/thread/f79e7d5e002b48f6).
To this end we had a method that did the following:
public void goToRelativePage(final String relativeURL) {
Window.Location.assign(GWT.getHostPageBaseURL() + relativeURL);
}