Does Symfony2 Dependency Injection support Object Lifestyle? - symfony

I have a class which I load via dependency injection within Symfony 2.
It has a number of default private variables which I can override with setters.
Problem is, once one of those default values are set to something else within a page, there is no way to set it back automatically.
I don't want to call the class again using new as it removes the usefulness of the dependency injection.
So, does Symfony2 support Object LifeStyle, or do I basically need to write a public function which resets all of the defaults back to normal and call it each time it is required.
As an example, I use a class to get remote files. It has defaults for UserAgent, Accepted Language/Encoding, Method etc. But if I set the Method to POST, instead of the default GET for one call in a page, the next time I call it, it is still POST, where as I wish it to be the default GET once more, which it would be if I used new instead of via dependency injection.

Add scope: prototype to your service definition. This will ensure you get a new instance from the container each time you request your class. And of course the instance will have the default values.
http://symfony.com/doc/current/cookbook/service_container/scopes.html

Related

What is the point of #WebInitParam?

#WebInitParam is an annotation that goes at class level.
It defines initialization parameters for the servlet.
I would like to know, what is the difference between doing this and using static variables, and why do it the #WebInitParam way rather than using statics?
What does defining k/v pairs as #WebInitParams allow you to do that you couldn't do if you declared static variables instead?
I have looked and all I can find is a million people saying how to define #WebInitParams. Well yes that's the easy bit. It's what I can do with that that is really what is of interest.
Thanks very much.
From a "raison d'etre" perspective, the annotation exists as a better design and architecture alternative to just peppering a class with static fields. #WebInitParam is a self-documenting approach to the initialization parameters a servlet or filter class needs, available via web.xml as well. It serves this purpose for the end developers as well as the JavaEE platform as a whole.
Think about it this way: in a vanilla project, you have the option of hardcoding a bunch of parameters in the class as static fields, or defining the same parameters in a property file. Which would you pick? Under what circumstances?
From a purely functional angle, apart from the function of using the annotation to override defaults set in web.xml, one other major reason is that you will sometimes need to get a hold of those initialization parameters from another component in your application. Using the annotation essentially increases the visibility of the parameter. In JSF for example, the API allows you to retrieve FacesServlet initialization parameters with:
//get all the parameters
FacesContext.getCurrentInstance().getExternalContext().getInitParameterMap()
//get a specific parameter
FacesContext.getCurrentInstance().getExternalContext().getInitParameter("aParameter");
In JSF-2.3 , it gets even more convenient with the following CDI-enabled injection:
#InitParameterMap Map<String,String> servletParameterMap;
Bear in mind that because it's CDI, it means this facility is available throughout the JavaEE platform, not just in web applications/JSF.
It's going to be a hassle to retrieve init parameters if the only mechanism available is a static field in the servlet class - you'll need to obtain an instance of the filter or servlet to get the static fields in it.
Separately, one could make the argument that maybe one should favour context-params over servlet-params because then, you get even more flexibility that isn't tied to any given servlet. That's a separate matter entirely :)

How Can I make Spring-MVC #PropertySources load first, before any other configuration

I have a spring-mvc application that is using java configuration, not xml. There are #Configuration annotations sprinkled through several files. In particular, there is a #PropertySources annotation in one file in a class that implements WebMvcConfigurerAdapter. There are two classes which contain an #Autowired Environment variable. One of these classes is itself a #Configuration class, and I would like it to have access to the fully-loaded Environment at the time it runs.
This isn't happening. When this code executes, the Environment is still null. I've tried reordering the #ComponentScan packages, tried moving the #PropertySources annotation, and nothing has helped me load the property sources in time.
I want this to happen first, before any other configuration.
What must I do to make it so?
UPDATE: After trying many things, including the Order annotation, I find the problem seems to be not so much that the #PropertySources are being loaded too late as that a class I have that is derived from org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer is being loaded too soon. Nothing in my code even references this class but Spring is somehow deciding that this, above all other classes, must be initialized first. No amount of messing around with #Order seems to change this. This in spite of the javadocs, which indicate that the behavior I want is the default:
Caveats
Subclasses of AbstractDispatcherServletInitializer will register their
filters before any other Filter. This means that you will typically
want to ensure subclasses of AbstractDispatcherServletInitializer are
invoked first. This can be done by ensuring the Order or Ordered of
AbstractDispatcherServletInitializer are sooner than subclasses of
AbstractSecurityWebApplicationInitializer.
You can use ContextInitializer, catch the moment when Boot prepared its environment and "inject" your property source programmatically as you want.
If you have a ConfigurableApplicationContext then it provides a ConfigurableEnvironment, which contains the propertySources as a list. If you want your PropertySource to rule all above the others than add it as first. If you want to place it to a special position then you can add it before an other, identified by its "name".
public class ConfigInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
#Override
public void initialize(ConfigurableApplicationContext ctx) {
// rule over all the others:
ctx.getEnvironment().getPropertySources().
addFirst(new ResourcePropertySource("file:/etc/conf/your_custom.properties"));
// rule over application.properties but not argument or systemproperties etc
ctx.getEnvironment().getPropertySources().
addBefore("applicationConfig: [classpath:/application.properties]",
new ResourcePropertySource("classpath:your_custom.properties"));
// names can be discovered by placing a breakpoint somewhere here and watch
// ctx.getEnvironment().getPropertySources().propertySourceList members,
// each has a name ...
}
}
You can bring into play this class by:
registering it in the application.properties :
context.initializer.classes=a.b.c.ConfigInitializer
or from application start :
new SpringApplicationBuilder(YourApplication.class).
initializers(new ConfigInitializer()).
run(args);
By the way this is a proper way to inject more of your custom properties, like properties coming from a database or a different host etc...
Not that I am an expert in Java config but maybe:
Spring 4 utilizes this feature in its #PropertySource annotation. To
remind you, #PropertySource annotation provides a mechanism for adding
a source of name/value property pairs to Spring's Environment and it
is used in conjunction with #Configuration classes.
Taken from: http://blog.codeleak.pl/2013/11/how-to-propertysource-annotations-in.html
Are you using #PropertySource or #PropertySources?
Have You tried 'order' property for spring bean initialisation?

Functionality change while upgrading to Castle Windsor 3.3.0 from 3.2.0

I am attempting to migrate from version 3.2.0 to 3.3.0. I am getting a compile error. I could not find an entry in the "Breaking Changes" section but here are my two errors in hope someone can guide me to a workable alternative.
public void RegisterTypeSingleton<T>(Type component, string name)
{
if (_container.Kernel.HasComponent(name))
_container.Kernel.RemoveComponent(name);
_container.Register(Component.For<T>().ImplementedBy(component).Named(name).LifeStyle.Singleton);
}
It seems Kernel.RemoveComponent() function has been depreciated. What has replaced this?
The second compiler error is at _container.Register(Component.For<T>().ImplementedBy(component).Named(name).LifeStyle.Singleton);
I am getting "The Type 'TService' must be a reference type in order to use it as a parameter.
I think you might be upgrading from an older version than 3.2.0. See below.
The removal of IKernel.RemoveComponent() is documented in the Breaking Changes document with v3.0.0. Here is the extract where Krzysztof explains why it was removed:
change - Removed the following methods:
GraphNode.RemoveDepender,
GraphNode.RemoveDependent,
IKernel.RemoveComponent,
IKernelEvents.ComponentUnregistered,
INamingSubSystem.this[Type service],
INamingSubSystem.GetHandler,
INamingSubSystem.GetService2Handler,
INamingSubSystem.GetKey2Handler,
INamingSubSystem.UnRegister(String key),
INamingSubSystem.UnRegister(Type service)
Also INamingSubSystem.Register now takes only IHandler as its argument
impact - low
fixability - none
description - The methods were implementation of "remove component from the container" feature
which was flawed and problematic, hecen was scraped.
fix - Working around is quite dependant on your specific usage. Try utilizing IHandlerSelectors.
For changed Register method, just update your calling code not to pass the name.
handler.ComponentModel.Name is now used as the key, as it was happening in all places so far
anyway, so this change should have no real impact.
RegisterComponent() won't overwrite an existing service registration, it'll just register another component for the same service, unless you specify the same name where it'll throw an exception informing you there is another component registered with that name. If your application doesn't replace components very often you could use the IsDefault() method on the registration to get Windsor to resolve the new component by default, just note the other component is still registered.
If your application replaces components often and you don't want the other registrations left there, you'd be best using a custom IHandlerSelector or ISubDependencyResolver so Windsor will ask you each time what component you want used for a specific service.
Also in v3.0.0 a change was made to ensure that value types cannot be passed to the registration methods. You'll need to add a generic constraint to your method that accepts a generic parameter so that it also only accepts reference types:
public void RegisterTypeSingleton<T>(Type component, string name)
where T : class
{
...
}

Logging method name , input parameters , date and time with using Attribute

i just want to make a class that inherited from Attribute class to put attribute tags in every method in my project to write the method name , Class name that have this method , date and time of calling , parameters and method's return ( if it's return something ).
i create a table in SQL Server that will receive all log information and sign it ..
i have done all the methods & query that interact with my database ( except Date & Time method) , the only problem is i don't know how to use it with Attribute way to get the information i have mention.
If you want logging with attributes, you may use PostSharp that modifies IL during compilation of your code and puts your logging codes before/after the method that you put your custom attribute derived from PostSharp's attributes (aspects)(AOP).
I think you can not do this only by use of custom attributes, because as I know custom attributes are instantiated only when Type.GetCustomAttributes() is called. So you may have to do some reflection business for sending your logs through your attributes that I don't recommend.
Instead of attributes, you can simply use AOP through a third party tool. You can use Castle Dynamic Proxy 's interceptor.
You can also log with attributes by using Interception in Castle Windsor.
To do this, you create a class that inherits from IInterceptor, register it with your container, then you can add an attribute to any class or method you want to add the logging behaviour to.
I've written an explanation here:
http://www.paulsodimu.co.uk/Post/Aspect-Oriented-Programming-Using-Castle-Windsor
And I've created a sample on GitHub to show how its done:
https://github.com/PaulSodimu/LoggingAopCastle

Asp.net MVC RouteBase and IoC

I am creating a custom route by subclassing RouteBase. I have a dependency in there that I'd like to wire up with IoC. The method GetRouteData just takes HttpContext, but I want to add in my unit of work as well....somehow.
I am using StructureMap, but info on how you would do this with any IoC framework would be helpful.
Well, here is our solution. Many little details may be omitted but overall idea is here. This answer may be a kind of offtop to original question but it describes the general solution to the problem.
I'll try to explain the part that is responsible for plain custom HTML-pages that are created by users at runtime and therefore can't have their own Controller/Action. So the routes should be either somehow built at runtime or be "catch-all" with custom IRouteConstraint.
First of all, lets state some facts and requirements.
We have some data and some metadata about our pages stored in DB;
We don't want to generate a (hypothetically) whole million of routes for all of existing pages beforehand (i.e. on Application startup) because something can change during application and we don't want to tackle with pushing the changes to global RouteCollection;
So we do it this way:
1. PageController
Yes, special controller that is responsible for all our content pages. And there is the only action that is Display(int id) (actually we have a special ViewModel as param but I used an int id for simplicity.
The page with all its data is resolved by ID inside that Display() method. The method itself returns either ViewResult (strongly typed after PageViewModel) or NotFoundResult in case when page is not found.
2. Custom IRouteConstraint
We have to somewhere define if the URL user actually requested refers to one of our custom pages. For this we have a special IsPageConstraint that implements IRouteConstraint interface. In the Match() method of our constraint we just call our PageRepository to check whether there is a page that match our requested URL. We have our PageRepository injected by StructureMap. If we find the page then we add that "id" parameter (with the value) to the RouteData dictionary and it is automatically bound to PageController.Display(int id) by DefaultModelBinder.
But we need a RouteData parameter to check. Where we get that? Here comes...
3. Route mapping with "catch-all" parameter
Important note: this route is defined in the very end of route mappings list because it is very general, not specific. We check all our explicitly defined routes first and then check for a Page (that is easily changeable if needed).
We simply map our route like this:
routes.MapRoute("ContentPages",
"{*pagePath}",
new { controller = "Page", action = "Display" }
new { pagePath = new DependencyRouteConstraint<IsPageConstraint>() });
Stop! What is that DependencyRouteConstraint thing appeared in mapping? Well, thats what does the trick.
4. DependencyRouteConstraint<TConstraint> class
This is just another generic implementation of IRouteConstraint which takes the "real" IRouteConstraint (IsPageConstraint) and resolves it (the given TConstraint) only when Match() method called. It uses dependency injection so our IsPageConstraint instance has all actual dependencies injected!
Our DependencyRouteConstraint then just calls the dependentConstraint.Match() providing all the parameters thus just delegating actual "matching" to the "real" IRouteConstraint.
Note: this class actually has the dependency on ServiceLocator.
Summary
That way we have:
Our Route clear and clean;
The only class that has a dependency on Service Locator is DependencyRouteConstraint;
Any custom IRouteConstraint uses dependency injection whenever needed;
???
PROFIT!
Hope this helps.
So, the problem is:
Route must be defined beforehand, during Application startup
Route's responsibility is to map the incoming URL pattern to the right Controller/Action to perform some task on request. And visa versa - to generate links using that mapping data. Period. Everything else is "Single Responsibility Principle" violation which actually led to your problem.
But UoW dependencies (like NHibernate ISession, or EF ObjectContext) must be resolved at runtime.
And that is why I don't see the children of RouteBase class as a good place for some DB work dependency. It makes everything closely coupled and non-scalable. It is actually impossible to perform Dependency Injection.
From now (I guess there is some kind of already working system) you actually have just one more or less viable option that is:
To use Service Locator pattern: resolve your UoW instance right inside the GetRouteData method (use CommonServiceLocator backed by StructureMap IContainer). That is simple but not really nice thing because this way you get the dependency on static Service Locator itself in your Route.
With CSL you have to just call inside GetRouteData:
var uow = ServiceLocator.Current.GetService<IUnitOfWork>();
or with just StructureMap (without CSL facade):
var uow = ObjectFactory.GetInstance<IUnitOfWork>();
and you're done. Quick and dirty. And the keyword is "dirty" actually :)
Sure, there is much more flexible solution but it needs a few architectural changes. If you provide more details on exactly what data you get in your routes I can try to explain how we solved our Pages routing problem (using DI and custom IRouteConstraint).

Resources