Is there any way to set an object of an anonymous type through Spring.Net?. Really, I've two questions:
Through ExpressionEvaluator (that's what I want to know principally)
Through IOC
The object I want to create is like the following:
new { reference = "formid" }
Thanks a lot
Related
I've read a lot on the subject of IoC containers and particularly Mark Seemann's blog posts, where he emphasises the importance of convention over configuration. I understand and agree with his point, but I wonder how best to mark out a class for an irregular lifetime?
For example, most of my services are registered with a Transient lifetime - but I want a particular service to be registered as a Singleton because it does some useful caching.
I have thought about using some custom attributes, but I have read arguments against this (because it puts composition logic in the class).
I have had this same debate with, for example, dependencies on configuration primitives. Ultimately I ended up using a parameter attribute because it worked in my case, but I feel that perhaps I didn't see the 'hidden dangers'.
It is common for an IoC container to allow you to specify the lifestyle of an object. SimpleInjector, for example, provides Transient and Singleton out of the box (and also allows the user to create a custom lifestyle class). With SimpleInjector it's as simple as:
container.Register<ISvc, Impl>(Lifestyle.Singleton);
or
container.Register<ISvc, Impl>(Lifestyle.Transient);
No need for polluting your classes with composition logic.
As for configuration primitives, a common practice is to put those behind an interface. I put my connection string behind an IDatabaseConfiguration interface, for example, and its implementation reads the value from web.config. I then inject that interface into my data services.
EDIT: Disregard above. Keeping it in so that comments make sense.
The following doesn't actually answer the question, but it may solve the problem that prompted the question. You said that the class does some useful caching, which clues me in on that it is taking on an additional responsibility. I would therefore recommend that you do not attempt to register that single implementation as a singleton, but instead create a decorator class around that implementation.
container.RegisterDecorator(
typeof(ICommandHandler<>),
typeof(CommandHandlerCacheDecorator<>),
Lifestyle.Transient,
x => { return /*some logic that looks for and
finds that one class you want
to decorate*/
});
The decorator needs to be a transient, because it will have a transient reference to the command it decorates. However, it could then access a separate singleton class (via dependency injection of course) or cache object that handles the actual caching.
EDIT: Examples to single out the one class to decorate. There are plenty of options depending on just how specific you want to be. Again this is with SimpleInjector, but I'm sure other containers have their own analogues.
//decorate a specific class
x => { return x.ImplementationType.FullName == "My.Commands.Web.SomeName"; }
//decorate all classes that share a certain namespace
x => { return x.ImplementationType.Namespace.EndsWith("Commands.Web"); }
//decorate all classes that implement the same interface
x => { return x.ImplementationType.IsInstanceOfType(typeof(ICouldCache)); }
I am looking at structuremap as an IOC/DI tool. Looking at this example:
http://docs.structuremap.net/QuickStart.htm
The only thing that does not make sense is, if I have an interface and derive several concrete types from it, in the code:
public class ClassThatGetsAnIValidator
{
public void SaveObject(object objectToSave)
{
// Go get the proper IValidator from StructureMap
IValidator validator = ObjectFactory.GetInstance();
var notification = validator.Validate(objectToSave);
if (notification.IsValid())
{
// save the object
}
}
}
How do I know which validator I get? IE I may have an AlphaBetValidator, NumericValidator, etc, with different method bodys and so on.....
I think this is the point:
Registering "what" and "how" StructureMap should build or find those requested services (the tedious part, but it's gotten much better over the years)
Which I struggle to grasp.
Please help.
Thanks
From the documentation:
If there is only one Instance for a registered PluginType, that
Instance will be assumed to be the default for the PluginType.
Otherwise, if there is more than one Instance for a PluginType,
StructureMap must be explicitly told which Instance is the default,
otherwise the call to GetInstance() will throw an exception (202).
To resolve to a particular instance you could use the naming mechanism. From the same documentation page:
Sometimes it's advantageous to retrieve a "named" instance of a type.
Let's say that you're building a system that needs to connect to
interface with multiple external shipping systems. You've designed an
interface for your system called IShippingSystem that hides the
details of each external shipping behind adapters. The rest of your
code should only "know" how to interact with the IShippingSystem, but
at some point, some class needs to know how to select and retrieve the
proper instance of IShippingSystem. Before the advent of IoC
containers like StructureMap, you would have coded a Factory class and
possibly a Builder class by hand to do the construction. With
StructureMap, this code is simply a call to the
ObjectFactory.GetNamedInstance(Type, string) method.
IShippingService internationalService = ObjectFactory.GetNamedInstance<IShippingService>("International");
IShippingService domesticService = ObjectFactory.GetNamedInstance<IShippingService>("Domestic");
When creating an service container in Symfony2 you mostly pass "static" arguments (like other classes etc.) to its constructor.
However I'd like to create a factory and therefore I need to be able to pass an dynamic argument to the service constructor.
The examples I found ( e.g. http://symfony.com/doc/current/cookbook/service_container/factories.html) are all ending up using static arguments as argument.
But what do I have to do, if I want my factory to decide which object to return based on (for example) user input?
I have some problems understanding why service factory should not work on your case. Do you need to return different service class unrelated to each other?
What I see from the factory example is that you could do something like this:
class NewsletterFactory
{
public function __constructor(...)
{
// Receive arguments needed to create the service below
}
public function get()
{
// Say the variable $userInput exists and is derived from constructor
if ($userInput === 'string')
return new NewsletterManager($dynamicArgument1);
if ($userInput === 'integer')
return new AnotherNewsletterManager($dynamicArgument2);
return new DefaultNewsletterManager();
}
}
Now, if this doesn't fit your needs. You can also create a service say CustomFactory that returns what you need. What is returned is not directly a service, so you can do whatever you want. But this would prevent you from requesting the objects created by CustomFactory from the dependency container.
Similar to that is the FormFactory. It is the factory used to instantiate form type. But the FormFactory is more powerfull since it is coupled with a dependency injection tag and a compiler pass, which register each types into the dependency injection system so they can be retrieved on their own. I don't exactly all the internals of the Form component but I think it could solve your problem if other methods do not.
Regards,
Matt
I'm new to this IoC and DI business- I feel like I get the concept if you are passing along objects that are of a global scope, but I don't get how it works when you need to pass around an object that is of a specific logical state. So, for instance, if I wanted to inject a person object into a write file command object- how would I be able to choose the correct person object dynamically? From what I have seen, I could default construct the object, but my disconnect is that you wouldn't use a default person object, it would need to be dynamic. I assume that the IoC container may just maintain the state of the object for you as it gets passed around, but then that assuems you are dealing in only one person object because there would be no thread safety, right? I know I am missing something, (maybe something like a factoryclass), but I need a little more information about how that would work.
Well, you can always inject an Abstract Factory into your consumer and use it to create the locally scoped objects.
This is sometimes necessary. See these examples:
MVC, DI (dependency injection) and creating Model instance from Controller
Is there a pattern for initializing objects created via a DI container
Can't combine Factory / DI
However, in general we tend to not use DI for Entities, but mostly for Services. Instead, Entities are usually created through some sort of Repository.
When you construct an service object (e.g. WriteFileService), you inject into it things it needs internally to complete it's job. Perhaps it needs a filesystem object or something.
The Person object in your example should be passed to the service object as a parameter to a method call. e.g. writeFileService.write(person)
There's something I just don't get about guice: According to what I've read so far, I'm supposed to use the Injector only in my bootstrapping class (in a standalone application this would typically be in the main() method), like in the example below (taken from the guice documentation):
public static void main(String[] args) {
/*
* Guice.createInjector() takes your Modules, and returns a new Injector
* instance. Most applications will call this method exactly once, in their
* main() method.
*/
Injector injector = Guice.createInjector(new BillingModule());
/*
* Now that we've got the injector, we can build objects.
*/
RealBillingService billingService = injector.getInstance(RealBillingService.class);
...
}
But what if not all Objects I ever need can be created during startup? Maybe I want to respond to some user interaction when the application is running? Don't I have to keep my injector around somewhere (e.g. as a static variable) and then call injector.getInstance(SomeInterface.class) when I need to create a new object?
Of course spreading calls to Injector.getInstance() all over the place seems not to be desirable.
What am I getting wrong here?
Yes, you basically only should use the Injector to create get the instance for the root-object. The rest of the application shouldn't touch the Guice-Container. As you've noticed, you still need to create some objects when required. There are different approaches for doing that, each suitable for different needs.
Inject a Provider
Provider is a interface from Guice. It allows you to request a new instance of a object. That object will be created using Guice. For example.
class MyService{
private Provider<Transaction> transactionProvider;
public MainGui(Provider<Transaction> transactionProvider){
this.transactionProvider = transactionProvider;
}
public void actionStarted(){
Transaction transaction = transactionProvider.get();
}
Build a Factory
Often you need some kind of factory. This factory uses some injected services and some parameters and creates a new object for you. Then you use this factory for new instances. Then you inject that factory and use it. There also help for this with the AssistedInject-extension
I think with these two possibilities you rarely need to use the Guice-Injector itself. However sometimes is still appropriate to use the injector itself. Then you can inject the Injector to a component.
To extend on the answer Gamlor posted, you need to also differentiate between the object types you are using.
For services, injection is the correct solution, however, don't try to always make data objects (which are generally the leafs in your object graph) injectable. There may be situations where that is the correct solution, but injecting a Provider<List> is probably not a good idea. A colleague of mine ended up do that, it made the code base very confusing after a while. We just finished cleaning it all out and the Guice modules are much more specific now.
In the abstract, I think the general idea is that if responding to user events is part of the capabilities of your application, then, well...
BillingService billingService = injector.getInstance(BillingService.class);
billingService.respondToUserEvent( event );
I guess that might be a little abstract, but the basic idea is that you get from Guice your top-level application class. Judging from your question, I guess that maybe BillingService isn't your top-level class?