I'm fairly familiar with the whole concept of IoC/DI, but I've never implemented a solution before. This is my first time, so please feel free to give me a push in the right direction if you deem it necessary.
I've got multiple classes that implement the same Interface(IMyCustomFileReader). I need to use one of these instances based on some Vendor information in my application. If the Vendor is Vendor1 I would like the IoC container to give me Vendor1FlatFileReader and DummyClass1 when I request an instance of IMyCustomFileReader and IDummyInterface respectively.
Similarly I would like the container to return instances of XMLFileReader and DummyClass2 when the Vendor is Vendor2.
I think (and let me know when I'm wrong) that I can use it using ChildContainers. At the moment my xml looks like this:
<components>
<component id="Vendor1"
service="SomeAssembly.IMyCustomFileReader, SomeAssembly"
type="SomeAssembly.Vendor1.Vendor1FlatFileReader, SomeAssembly.Vendor1">
</component>
<component id="Vendor1"
service="SomeAssembly.IDummyInterface, SomeAssembly"
type="SomeAssembly.DummyClass1, SomeAssembly">
</component>
<component id="Vendor2"
service="SomeAssembly.IMyCustomFileReader, SomeAssembly"
type="SomeAssembly.XMLFileReader, SomeAssembly">
</component>
<component id="Vendor2"
service="SomeAssembly.IDummyInterface, SomeAssembly"
type="SomeAssembly.DummyClass2, SomeAssembly">
</component>
</components>
This configuration is erroneous as I cannot have multiple components with the same id element - Not even when the Interfaces are different like in the above example. I was hoping I could do something like Container.Resolve<IMyCustomFileReader>("Vendor1"), then when an instance of IMyCustomFileReader is requested and the key value is Vendor1 I would get back an instance of Vendor1FlatFileReader.
I get a Castle.MicroKernel.ComponentRegistrationException when I try to do it this way.
Something else I think might work is the concept of ChildContainers, but how would I go about configuring those in xml?
Also, I would prefer not to give my components names like Vendor1_IMyCustomFileReader and Vendor2_IMyCustomFileReader. I would also prefer to have only 1 configuration file and not separate ones for each Vendor (if possible). Has anyone else encountered a similar problem before? How can I solve this?
Yes, component ids must be unique. I wouldn't recommend child containers unless you really know what you're doing. In this case, it looks like you're trying to do some sort of multi-tenancy, so I recommend taking a look at handler selectors, this will let you select the appropriate component based on the "vendor" without resorting to service location (if you do container.Resolve() in application-level code, you already lost).
Would you be willing to use the fluent registration API? If so, you could decide which components to register at runtime based on the "vendor" (the registrations for each vendor could live in a separate IWindsorInstaller implementation). This solution assumes you know which "vendor" to use at start-up and that the "vendor" will not change throughout the lifetime of the application (I'm guessing that is a valid assumption based on how you stated the question). You could take a similar approach with XML configuration, but you would need to separate the configuration for each vendor into separate config files, and you say you are opposed to that -- could you clarify why?
Please comment and let me know if you think that the fluent API approach could work, and I'd be happy to post an example.
Related
Let's say I have a bunch of kittens. Perhaps I have a KittenViewModel. I want to show it as a kitten card in a card view, but also as broken down into columns in a list view. Does MvvmCross support binding the KittenViewModel to multiple views? Should I have multiple ViewModels that refer back to a single model?
Disclaimer: I know that I am replying to an old question which you may well have forgotten; this is for posterity. Also, I have limited understanding of the MVVM design pattern. I remember reading somewhere that Views and ViewModels are typically in 1-to-1 correspondence, so the conventional answer is probably "You shouldn't do that. Reconsider your design."
With that being said, I recently struggled with this for a while before coming up with a very simple solution that operates under the following assumptions: (1) you wish to use the exact same instance of a ViewModel in two separate Views; (2) for whatever reason, you cannot use a DataTemplateSelector to determine which View to use; and (3) you do not mind creating multiple Views for the same ViewModel.
The solution is to define separate data templates for the KittenViewModel as resources for whatever controls you are going to use to display the data. For example, if you have created a KittenCardView user control and intend to display it in a ContentControl, you can set the DataTemplate in a ContentControl resource, something like:
<ContentControl>
<Control.Resources>
<DataTemplate DataType="{x:Type viewmodel:KittenViewModel}">
<view:KittenCardView/>
</DataTemplate>
</Control.Resources>
</ContentControl>
The KittenColumnView (or whatever you call it) would be handled similarly. You may find it helpful to define one of the Views as a Window or App resource if typically use one and only need the other in special circumstances.
First, some context: I drive qooxdoo from other languages such as Lisp and ClojureScript, and I dynamically generate code to reference individual classes.
This normally fails because the qooxdoo generator looks through the static source to see which classes to include.
In the past I have just whomped explicit mentions of classes into Application.js. This works great, but recently I started to grok the config.json syntax and thought it would be nice to take a less kludgy approach.
I managed to add code like this to the "source-build" job and that build then worked:
"include" : ["qx.ui.mobile.page.Manager"]
But I use many classes in an app, so adding that to each job would be error-prone and still ugly.
I tried adding the "include" to the "mobile-common" job which the other jobs extend but to my surprise that did not work. Hmm.. could there be a bug in the job "extend" logic?
I could just add "include" : ["qx.ui.mobile.*"] to all the jobs but that is still ugly and excessive (and I would have still to pull in multiple other classes in each job).
Looking back at all this, it seems there would be no problem if the job "extends" mechanism successfully picked up the "include" option. I just ran the generator with the verbose option -v and can confirm the page manager class is not included if I add the "include" to mobile-common, but it is if I do so on the specific job.
Am I missing something?
Kenny,
you're quite right using the "mobile-common" job, and it is really strange that it doesn't work. As I don't know your exact config.json file I can only provide some guesses here:
The default "mobile-common" job provided with the mobile skeleton already contains an "include" key. You did not by any chance add a second one to the job?!
Are you using the mobile config.json directly, or did you create another config file and are including the one that contains the default "mobile-common"? If you use job shadowing (i.e. define "mobile-common" in one config file but also in another which is included by the first), this will influence the content of the resulting job definition (maybe in an unexpected way).
The default "mobile-common" job has (for whatever reason) a = in front of the include key, to protect from overriding. You might want to remove that and see what happens.
If all fails you can still create your own includer job (like "my-includes"), add an "include" key to it, and then add this job to the "extend" list of the relevant source* and build* jobs. Make sure to add it before the mobile-common entry. This way you can at least maintain your additional include patterns in a single place.
Continuing to work on my port of a CakePHP 1.3 app to 3.0, and have run into another issue. I have a number of areas where functionality varies based on certain settings, and I have previously used a modular component approach. For example, Leagues can have round-robin, ladder or tournament scheduling. This impacts on the scheduling algorithm itself, such that there are different settings required to configure each type, but also dictates the way standings are rendered, ties are broken, etc. (This is just one of 10 areas where I have something similar, though not all of these suffer from the problem below.)
My solution to this in the past was to create a LeagueComponent with a base implementation, and then extend that class as LeagueRoundRobinComponent, LeagueLadderComponent and LeagueTournamentComponent. When controllers need to do anything algorithm-specific, they check the schedule_type field in the leagues table, create the appropriate component, and call functions in it. This still works just fine.
I mentioned that this also affects views. The old solution for this was to pass the league component object from the controller to the view via $this->set. The view can then query it for various functionality. This is admittedly a bit kludgy, but the obvious alternative seems to be extracting all the info the view might require and setting it all individually, which doesn't seem to me to be a lot better. If there's a better option, I'm open to it, but I'm not overly concerned about this at the moment.
The problem I've encountered is when tables need to get some of that component info. The issue at hand is when I am saving my add/edit form and need to deal with the custom settings. In order to be as flexible as possible for the future, I don't have all of these possible setting fields represented in the database, but rather serialize them into a single "custom" column. (Reading this all works quite nicely with a custom constructor and getters.) I had previously done this by loading the component from the beforeSave function in the League model, calling the function that returns the list of schedule-specific settings, extracting those values and serializing them. But with the changes to component access in 3.0, it seems I can no longer create the component in my new beforeMarshal function.
I suppose the controller could "pass" the component to the table by setting it as a property, but that feels like a major kludge, and there must be a better way. It doesn't seem like extending the table class is a good solution, because that would horribly complicate associations. I don't think that custom types are the solution, as I don't see how they'd access a component either. I'm leaning towards passing just the list of fields from the controller to the model, that's more of a "configuration" method. Speaking of configuration, I suppose it could all just go into the central Configure data store, but that's always felt to me like somewhere that you only put "small" data. I'm wondering if there's a better design pattern I could follow that would let the table continue to take care of these implementation details on its own without the controller needing to get involved; if at some point I decide to change from the serialized method to adding all of the possible columns, it would be nice to have those changes restricted to the table class.
Oh, and keep in mind that this list of custom settings is needed in both a view and the table, so whatever solution is proposed will ideally provide a way for both of them to access it, rather than requiring duplication of code.
In my Symfony2 app I'm having a very basic bundle named AnimalsBundle() with a very basic entity.
I can successfully extend this bundle by creating a new bundle MammalsBundle() via Bundle Inheritance. However, it is not possible to register one further bundle InsectsBundle() that also extends the AnimalsBundle(). Whenever I'm trying to do this, Symfony throws a
[LogicException]
Bundle "AnimalsTextBundle" is directly extended by two bundles "MammalsBundle" and "InsectsBundle".
So out of the box it's obviously not allowed. First of all, I'm not really sure why this is not allowed and - most important - how can I solve this?
I know it's been more than year now, but I just came across your question and the answer maybe useful to someone anyway..
Symfony doesn't allow a bundle to be extended directly by more than one bundle, simply because if two bundles are overriding the same files, it wouldn't be possible to determine what bundle should be used. However you can achieve what you want by doing the following :
AnimalsBundle <|---- MammalsBundle <|----- InsectsBundle
This way InsectsBundle indirectly has AnimalBundle as a parent and can override files from it.
I know, that this has been a log time since the question has been asked, but for those in need of an answer I'll suggest the following:
1) Try to avoid bundle inheritance except the cases you are 100% positive that you need to.
2) Given the example in question, the better setup will look smth like this: you have a CreatureBundle, which consists mostly of abstract classes and interfaces. Make each descendant bundle depend on CreatureBundle and implement each Creature specific code with those abstract classes and interfaces in CreatureBundle.
Based on personal experience I can tell that managing dependencies is much easier task than managing inheritance issues in case something goes wrong. If you'll ever need to alter the ancestor bundle's logic, you'll save yourself lot time by not having to dig through inherited code and alter the same logic in every descendant bundle.
Edit: Although my suggestions might lead to tighter coupling and basically contradicts latest Symfony's 'best practices' guide (which states that 'single bundle per app' is a best practice), in the end you'll realize that this approach eventually makes code maintenance easier.
I can't think of a use case where you could possibly need to do this. Bundles are meant to be almost like standalone applications. You have the dependency injection container at your disposal if you need resources from another bundle.
Perhaps you should re-think your project structure.
In all my projects till now, I use to use singleton pattern to access Application configuration throughout the application. Lately I see lot of articles taking about not to use singleton pattern , because this pattern does not promote of testability also it hides the Component dependency.
My question is what is the best way to store Application configuration, which is easily accessible throughout the application without passing the configuration object all over the application ?.
Thanks in Advance
Madhu
I think an application configuration is an excellent use of the Singleton pattern. I tend to use it myself to prevent having to reread the configuration each time I want to access it and because I like to have the configuration be strongly typed (i.e, not have to convert non-string values each time). I usually build in some backdoor methods to my Singleton to support testability -- i.e., the ability to inject an XML configuration so I can set it in my test and the ability to destroy the Singleton so that it gets recreated when needed. Typically these are private methods that I access via reflection so that they are hidden from the public interface.
EDIT We live and learn. While I think application configuration is one of the few places to use a Singleton, I don't do this any more. Typically, now, I will create an interface and a standard class implementation using static, Lazy<T> backing fields for the configuration properties. This allows me to have the "initialize once" behavior for each property with a better design for testability.
Use dependency injection to inject the single configuration object into any classes that need it. This way you can use a mock configuration for testing or whatever you want... you're not explicitly going out and getting something that needs to be initialized with configuration files. With dependency injection, you are not passing the object around either.
For that specific situation I would create one configuration object and pass it around to those who need it.
Since it is the configuration it should be used only in certain parts of the app and not necessarily should be Omnipresent.
However if you haven't had problems using them, and don't want to test it that hard, you should keep going as you did until today.
Read the discussion about why are they considered harmful. I think most of the problems come when a lot of resources are being held by the singleton.
For the app configuration I think it would be safe to keep it like it is.
The singleton pattern seems to be the way to go. Here's a Setting class that I wrote that works well for me.
If any component relies on configuration that can be changed at runtime (for example theme support for widgets), you need to provide some callback or signaling mechanism to notify about the changed config. That's why it is not enough to pass only the needed parameters to the component at creation time (like color).
You also need to provide access to the config from inside of the component (pass complete config to component), or make a component factory that stores references to the config and all its created components so it can eventually apply the changes.
The former has the big downside that it clutters the constructors or blows up the interface, though it is maybe fastest for prototyping. If you take the "Law of Demeter" into account this is a big no because it violates encapsulation.
The latter has the advantage that components keep their specific interface where components only take what they need, and as a bonus gives you a central place for refactoring (the factory). In the long run code maintenance will likely benefit from the factory pattern.
Also, even if the factory was a singleton, it would likely be used in far fewer places than a configuration singleton would have been.
Here is an example done using Castale.Core >> DictionaryAdapter and StructureMap