I am asking the same as the Question, How to access ServletContext from within a Vaadin 7 app?, but for Vaadin 14.
In Vaadin 7, Vaadin provided the simple and handy call:
ServletContext servletContext = VaadinServlet.getCurrent().getServletContext();
That particular call is no longer there on VaadinServlet in Vaadin 14.
➥ Is there an equivalent somewhere else in the Vaadin API?
My end goal is to use the key-value "attribute" collection to keep references to my app-wide objects.
Methods still there, but not documented
Both methods:
VaadinServlet.getCurrent() ➙ VaadinServlet
VaadinServlet::getServletContext() ➙ javax.servlet.ServletContext
…are there still in Vaadin 14.
It seems the second method, VaadinServlet::getServletContext(), isn't listed in the Javadocs because it's inherited from javax.servlet.GenericServlet and the Javadoc generation is run in a way that doesn't have access to that class.
VaadinContext
For the particular case of accessing attributes from ServletContext, there's a new VaadinContext abstraction introduced in Vaadin 14. It's added to make it possible for framework internals to access context attributes without being tied to the Servlet API. It can be accessed using VaadinService.getCurrent().getContext().
VaadinContext can track attributes by their class:
getAttribute(Class<T> type)
setAttribute(T value)
removeAttribute(Class<?> clazz)
Update: One of the Answers by Leif Åstrand explains both methods are actually present in Vaadin 14 but one is undocumented.
I verified that we can indeed call:
ServletContext servletContext = VaadinServlet.getCurrent().getServletContext();
So the rest of my Answer here is obsolete. I will leave my Answer as a curiosity, rather than delete it.
This may not be the best way, but it seems to be working for me.
The VaadinServletService class, extending com.vaadin.flow.server.VaadinService, offers the getCurrentServletRequest(). That method returns a javax.servlet.http.HttpServletRequest object. For there we can call javax.servlet.ServletRequest.getServletContext to return the javax.servlet.ServletContext you desire.
ServletContext servletContext =
VaadinServletService // com.vaadin.flow.server.VaadinServletService
.getCurrentServletRequest() // Returns a javax.servlet.http.HttpServletRequest
.getServletContext() // Returns a `javax.servlet.ServletContext`.
;
From there you can use the key-value "attribute" collection as you mentioned. Look to the setAttribute, getAttribute, and removeAttribute methods with a String object as the key and a Object as the value.
Saving.
DataSource dataSource = … ;
VaadinServletService.getCurrentServletRequest().getServletContext().setAttribute( "javax.sql.DataSource" , dataSource ) ;
Retrieving. The key-value collection of "attributes" keep the value as an Object, so we must cast back to the expected class/interface.
DataSource dataSource = (DataSource) VaadinServletService.getCurrentServletRequest().getServletContext().getAttribute( "javax.sql.DataSource" ) ;
Related
I am building an WPF application using the MVVM Light Toolkit and specifically SimpleIoc.
I have a parent viewmodel that dynamically creates child viewmodels. When doing this I am using "standard" dependency injection to pass a IConfigService as a parameter to the constructor. I want the IConfigService to be a unique instance for each child viewmodel. So I try this:
IConfigService service = SimpleIoc.Default.GetInstance<IConfigService>(key);
ChildViewModel vm = new ChildViewModel(service);
Where key is a unique identifier for each child viewmodel. According to the documentation of MVVM Light and SimpleIoc this GetInstance method:
...provides a way to get an instance of a given type corresponding to a given key. If no instance had been instantiated with this key before, a new instance will be created.
There is also a remark that the class must have been registered before, else it returns null. In my case it has been, in ViewModelLocator:
var configService = new ConfigService();
SimpleIoc.Default.Register<IConfigService>(() => configService);
However, the GetInstance call returns the same instance every time.
What am I doing wrong here?
You registered an already instantiated object.
SimpleIoc does not create its own instances with this overload. It always returns configService. Either you need to perform the instantiation within the lambda, because you are using a factory overload, or you can do this more easily by just passing the ConfigService type. SimpleIoc will take care of the instantiation itself.
I am creating some hack kind of thing in existing android code to verify database creation and its accessibility across layers in application.
For this I have modified an existing function of .java file but I am facing an issue while calling constructor of SQLiteOpenHelper.
The signature is SQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version)
And I don't know how to create this Context instance. From googling I am seeing it is being some kind of activity class instance.
What ways are there to create this Context instance? Do we have to have activity class implemented?
Have a look at this question. It shows how to obtain a reference to the current Context object statically.
The gist of it is that you have to store a reference to the context that can be accessed statically from other sections of code.
P.S. You can't really "create" a context. That is something that is provided to you by the Android platform.
Just call:
this.getApplicationContext()
from wherever you are trying to create the instance of SQLiteOpenHelper.
I have been adapting our code in preparation of moving our code to the new 2.1 Symfony codebase.
In 2.0.* we could set Flash messages by simply calling the session service in our controller using the following
$this->get('session')->setFlash('type', 'message');
I have trawled through the new documentation, I was just wondering if there was a clean way, similar to the above; rather than just calling the FlashBagInterface?
Try:
$this->get('session')->getFlashBag()->set('type', 'message');
Also, you might want to try the add() method instead, which won't obliterate other flash messages:
$this->get('session')->getFlashBag()->add('type', 'message');
FYI:
The Symfony HttpFoundation component has a very powerful and flexible session subsystem which is designed to provide session management through a simple object-oriented interface using a variety of session storage drivers.
FlashBagInterface has a simple API:
set(): Sets an attribute by key;
get(): Gets an attribute by key;
all(): Gets all attributes as an array of key => value;
has(): Returns true if the attribute exists;
replace(): Sets multiple attributes at once: takes a keyed array and sets each key => value pair;
remove(): Deletes an attribute by key;
clear(): Clear all attributes.
Source: Symfony2: Session Management
At a high level, how do these dep. injection frameworks work?
I can understand if you always instantiate an object via a custom factory like:
IUser user = DepInjector.Get<User>();
I'm guessing what happens is, wherever you defined the mappings, it will look at the type you want and try and find a match, if found, it will via reflection instantiate the type.
Are there dep. inj. frameworks that would work like:
IUser user = new User();
If so, how would it get the correct user, where is it hooking into the CLR to do this? In case of an asp.net website, is it any different?
If you want to know how Ninject works then the obvious place to start would be reading How Injection Works on their official wiki. It does use reflection but it now also uses dynamic methods:
"By default, the StandardKernel will
create dynamic methods (via
System.Reflection.Emit.DynamicMethod)
that can be used to inject values into
the different injection targets. These
dynamic methods are then triggered via
delegate calls."
As for you second example, I don't believe there are any DI frameworks that would do what you ask. However, constructor injection tends to be most common way of implementing IoC, so that when a class is constructed it knows what type to bind to via some configuration binding. So in your example IUser would be mapped to concrete User in config bindings so that any consuming class that has an IUser parameter as part of its constructor would get the correct User type passed in.
AFAIK there's no way to "hook into" object instantiation with the CLR. The only way to use DI in the second case would be to employ an assembly rewriter (i.e. a postprocessor similar to PostSharp) to replace the call to new with a call to the DI factory method (i.e. GetUser) in the compiled code.
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).