I'm experiencing an issue with Glass Mapper in my current project that I haven't encountered before.
Directly after Sitecore has been initialized, the Database property in my GlassContext (ISitecoreContext) is null.
// After Sitecore initialization, sometimes the glass context database is not initialized yet.
if (this.glassContext == null || this.glassContext.Database == null)
{
this.glassContext = DependencyInjection.Container.Resolve<ISitecoreContext>();
// Now I have a valid this.glassContext.Database ...
}
When I ask my DI framework (Windsor, so Glass' default) for an instance, it returns me one with a valid Database property.
For the time-being I'm doing this check before retrieving any items and it only needs this check one time (after that it's good until the next initialization), but would really like to know what is causing this.
Probably interesting to know: all item requests (getting items, casting items, etc.) are done through one service which gets the ISitecoreContext initialized in its constructor.
The ItemService has lifestyle Singleton, the ISitecoreContext has lifestyle Transient
I think that your NewsService was first time injected before Sitecore has a valid context, therefor Glass also cannot be have a valid context (database). Because your ItemService has a Singleton lifetime, the constructor is only called once and also the resolving of ISitecoreContext is done once. This means, if your ItemService is resolved the first time before Sitecore has a valid context, then your glassContext will be null. After you manually set the glassContext property in the Singleton instance, the next time it won't be null (but maybe not valid because you are in another request).
I would suggest you setting both dependencies either to Transient or to PerWebRequest.
As stated in other comments, sometimes this is due to not specifying an appropriate lifestyle. Transient may give you memory leaks if you do not find an appropriate way to Release it. I personally often use the NoTrackLifestyle that ships with Glass Mapper, since it behaves more like Transient from other containers.
There are also occasions where you can attempt to resolve the service too early, this in particular can happen when running in pipeline entries etc where the context has not yet been resolved for the request. In these instances you can use either a named instance where you specify the database and / or it's name as a dependency.
Bear in mind in all cases, the sitecore context / service by default relies on the CONTEXT database, if Sitecore hasn't resolved it yet - neither will glass have.
When using it with the new Glass Delegate functionality, I have found it necessary sometimes to rely on a factory implementation that delays the getting of the service, it's not perfect, but serves it's purpose since the fluent configuration often won't have a context available at the time of instantiation. By adding a small factory, it can be delayed until the delegate code is actually called.
public interface ISitecoreServiceFactory
{
// Gets the Sitecore service from the container
ISitecoreService GetService();
}
There are also instances sometimes with this when Glass is used in the creation of SPEAK / Sheer UI dialogs.
Related
The MSI installation would call my (native/C++) custom action functions. Since the DLL is freshly loaded, and the MSIEXEC.EXE process is launched separately for each function (the callable actions, as specified in MSI/WiX script), I cannot use any global data in C/C++ program.
How (or Where) can I store some information about the installation going on?
I cannot use named objects (like shared-memory) as the "process" that launches the DLL to call the "action" function would exit, and OS will not keep the named-object.
I may use an external file to store, but then how would I know (in the DLL's function):
When to delete the external file.
When to find that this function call is the first call (Action/function call Before="LaunchConditions" may help, not very sure).
If I cannot delete the file, I cannot know if "information" is current or stale (i.e. belonging to earlier failed/succeeded MSI run).
"Temporary MSI tables" I have heard of, but not sure how to utilize it.
Preserve Settings: I am a little confused what your custom actions do, to be honest. However, it sounds like they preserve settings from an older application and setup version and put them back in place if the MSI fails to install properly?
Migration Suggestion (please seriously consider this option): Could you install your new MSI package and delete all shortcuts and access to the old application whilst leaving it
installed instead? Your new application version installs to a new path
and a new registry hive, and then you migrate all settings on first
launch of the new application and then kick off the uninstall of the
old application - somehow - or just leave it installed if that is
acceptable? Are there COM servers in your old install? Other things that have global registration?
Custom Action Abstinence: The above is just a suggestion to avoid custom actions. There are many reasons to avoid custom actions (propaganda piece against custom actions). If you migrate settings on application launch you avoid all sequencing, conditioning, impersonation issues along with the technical issues you have already faced (there are many more) associated with custom action use. And crucially you are in a familiar debugging context (application launch code) as opposed to the unfamiliar world of setups and their poor debugability.
Preserving Settings & Data: With regards to saving data and settings in a running MSI instance, the built in mechanism is basically to set properties using Session.Property (COM / VBScript) or MsiSetProperty (Win32) calls. This allows you to preserve strings inside the MSI's Session object. Sort of global data.
Note that properties can only be set in immediate mode (custom actions that don't change the system), and sending the data to deferred mode custom actions (that can make system changes) is quite involved centering around the CustomActionData concept (more on deferred mode & CustomActionData).
Essentially you send a string to the deferred mode custom action by means of a SetProperty custom action in immediate mode. Typically a "home grown" delimited string that you construct in immediate mode and chew up into information pieces when receiving it in deferred mode. You could try to use JSON-strings and similar to make transfer easier and more reliable by serializing and de-serializing objects via JSON strings.
Alternatives?: This set property approach is involved. Some people write to and from the registry during installation, or to a temp file (in the temp folder) and then they clean up during the commit phase of MSI, but I don't like this approach for several reasons. For one thing commit custom actions might not run based on policies on target systems (when rollback is disabled, no commit script is created - see "Commit Execution" section), and it isn't best practice. Adding temporary rows is an interesting option that I have never spent much time on. I doubt you would be able to easily use this to achieve what you need, although I don't really know what you need in detail. I haven't used it properly. Quick sample. This RemoveFile example from WiX might be better.
This question is yet another follow-up to a previous question regarding the setup of DryIOC with MediatR and decorators: DryIOC and MediatR: Injection using InResolutionScopeOf for both IAsyncNotificationHandler and IAsyncRequestHandler
In this example, the setup is similar to the one of my previous question, we have requests (IAsyncRequestHandler) and notifications (IAsyncNotificationHandler), and the notifications are being fired from the requests, and both have a dependency on a DbContext with needs to be injected per resolution scope.
What I'm doing now is decorating IAsyncRequestHandler and i'm passing a dependency of type IActionHandler to the decorator using a key. I'm registering the dependency like this:
c.Register<IActionHandler, SomeActionHandler>(serviceKey: "key1");
And then, passing the parameter to the decorator like this:
c.Register(typeof(IAsyncRequestHandler<,>), typeof(Decorator<,>),
made: Parameters.Of.Type<IActionHandler>(serviceKey: "key1"),
setup: DryIoc.Setup.Decorator);
Set up like this, the notification is fired from the request handler successfully. However if I add more decorators and change the setup parameter of the decorator to DecoratorWith and specify a condition (even if it simply returns true), the notification isn't fired from the request handler because the DbContext isn't injected successfully into the IAsyncNotificationHandler.
Here is a fiddle which shows the problem https://dotnetfiddle.net/ob0nfA
When debugging, i found out that the condition in DecoratorWith of the first decorator is called twice for the same service type, when there are two registrations. I'm not sure if this is intended or not, however I believe that might be related to the problem, because if I simply return true, then multiple decorators will be registered for the same handler, when there should only be one.
I know I would be able to register the decorator dependencies using Made instead, but in this specific instance keyed registration seems better for my intended setup.
So I'd like to know if there's something I'm missing, or in the case that DecoratorWith works as intended by being called more than once for the same service type, I'd like to know if there is a way that I can distinguish the calls, so that i can register the decorator properly only once.
Or maybe the problem lies elsewhere entirely.
Thanks
Found the reason. In current DryIoc version 2.9.3 adding condition to decorator makes it context dependent (which is true btw). But then context dependent service is injected as resolution call instead expression inlining. Using resolution call here messes up with resolution scopes (not yet 100% clear yet how).
So if I remove the switch to resolution call for context dependent decorators, your code works again.
Fix will be released soon. I will update my answer with the fix version.
Update with fix:
Problem is fixed in DryIoc 2.9.5
This question is a follow up to my previous question, DryIOC Decorator and InResolutionScopeOf
What I'm trying to do is create EF DbContext instances in the resolution scope of both IAsyncRequestHandler and IAsyncNotificationHandler, meaning the context injected in a request can't be the same as one injected in a notification (published from a request). Since the notifications are published from inside the request handlers, this nesting is creating some troubles with my desired setup.
It is worth noting that each DbContext injected in a given IAsyncRequestHandler or IAsyncNotificationHandler instance needs to be the same across their own decorators.
I've created a dotnetfiddle with my attempt at setting this up https://dotnetfiddle.net/KiFCHY. (I've ommitted decorators in this example)
It contains a RequestHandler which prints a message when it is called, and it then publishes a notification, which prints another message. However, as you can see, the notification isn't called because MediatR cannot get the IAsyncNotificationHandler instance (because it can't resolve the DbContext).
Is this setup possible?
Thanks
Found the root cause: ResolveMany<object>(serviceType) which is used in MediatR setup.
An object identifies that you need to pass run-time required serviceType. But DryIoc has an issue of using service type object instead of required type to find the matching resolution scope. And an object is definitely not assignable to IAsyncNotificationHandler<T>.
Here is the modified fiddle
Stay tuned for the fix. I will update my answer with the fix version.
Updated with fix version
The fix is released with DryIoc 2.9.2. Here is fiddle which uses it. Thanks for asking and surfacing 2 issues - real use cases matter the most.
In ember's blog post about 1.12 release, mentions an example using application.deferReadiness inside an instance initializer. However, it doesn't seem to be working. The first parameter to the initialize function doesn't have a deferReadiness method. Any ideas?
I think it's reasonable to post #tomdale explanation here as an answer.
#tomdale: "It's not possible to defer app readiness in an instance initializer, since by definition instance initializers are only run after the app has finished booting.
Sidebar on the semantics of application booting: "App readiness" (as in, deferReadiness() and advanceReadiness()) refers to whether all of the code for the application has loaded. Once all of the code has loaded, a new instance is created, which is your application.
To restate, the lifecycle of an Ember application running in the browser is:
Ember loads.
You create an Ember.Application instance global (e.g.
App).
At this point, none of your classes have been loaded yet.
As your JavaScript file is evaluated, you register classes on the
application (e.g. App.MyController = Ember.Controller.extend(…);)
Ember waits for DOM ready to ensure that all of your JavaScript
included via <script> tags has loaded.
Initializers are run.
If you need to lazily load code or wait for additional setup, you can call deferReadiness().
Once everything is loaded, you can call advanceReadiness().
At this point, we say that the Application is
ready; in other words, we have told Ember that all of the classes
(components, routes, controllers, etc.) that make up the app are
loaded.
A new instance of the application is created, and instance
initializers are run.
Routing starts and the UI is rendered to the
screen.
If you want to delay showing the UI because there is some runtime setup you need to do (for example, you want to open a WebSocket before the app starts running), the correct solution is to use the beforeModel/model/afterModel hooks in the ApplicationRoute. All of these hooks allow you to return a promise that will prevent child routes from being evaluated until they resolve.
Using deferReadiness() in an initializer is an unfortunate hack that many people have come to rely on. I call it a hack because, unlike the model promise chain in the router, it breaks things like error and loading substates. By blocking rendering in initializers, IMO you are creating a worse experience for users because they will not see a loading or error substate if the promise is slow or rejects, and most of the code I've seen doesn't have any error handling code at all. This leads to apps that can break with just a blank white screen and no indication to the user that something bad has happened."
See also discussion: https://github.com/emberjs/ember.js/issues/11247
According to http://emberjs.com/guides/object-model/classes-and-instances/ it is required to access properties using getters and setters:
When accessing the properties of an object, use the get and set accessor methods.
Make sure to use these accessor methods; otherwise, computed properties won't recalculate, observers won't fire, and templates won't update.
I understand that it is needed to use setters when changing property to let Ember know about the change so it can update bindings, but what about reading properties?
Example from http://emberjs.com/guides/object-model/classes-and-instances/
App.Person = Ember.Object.extend({
say: function(thing) {
var name = this.get('name');
alert(name + " says: " + thing);
}
});
var yehuda = App.Person.create({
name: "Yehuda Katz"
});
yehuda.say("Yes");
In the example above, this.get('name') is used to access property name, however method say is defined as a property of class App.Person and is accessed directly by dot notation. While there is a distinctive usage difference between method and property, in JavaScript, there's no difference in implementation of both. The example still works if I replace this.get('name') by this.name.
Are there any implementation differences in Ember regarding methods and properties of object?
Is it always safe to access methods directly?
Must all properties including computed properties be always accessed by getter? If not, when is it safe to access properties directly?
I definitely want to stick to best practise here, which is to use getter/setter every time, but I'd like to understand the internals of Ember.js :)
The definition of a method or a property in Ember is the same as in Vanilla JavaScript, but they are resolved different in Ember. You are not working with POJOs. Every time you extend from a Route/Controller/View, you are adding the Ember layer that processes methods and properties differently.
No, is not always safe. In your case it is because it is overly simple.
Yes, always access properties with get.
User interaction with your app is what causes changes in the properties of your objects, we handle those interactions with events. When an event in Ember is fired, it is not resolved immediately, instead it is put in a priority queue and resolved at a later time.
Properties are updated and read in an asynchronous form, if you access them directly using this there is no guarantee that you'll get the most up to date value.
Check: Managing Asynchrony
When you make a change to a property in Ember, it does not immediately propagate that change. Instead, it invalidates any dependent properties immediately, but queues the actual change to happen later.
So, when you change the value of a property, this is roughly what happens:
A property is changed
All dependent properties are invalidated
Queues the actual change for later
Wait for any other event handlers, for the current user, to finish
Flush the changes queue
Until here, the property is actually updated (and this would work as usual)
Imagine you use this to read a property, but some other event occurs that changes its value. The new value won't be available until the queue is flushed, but this reads immediately the property and returns the value of a property that is scheduled to be updated soon. You get stale data. The methods get and set manage this asynchrony for you and guarantee fresh values always.
When you have only one property, in the whole app, this asynchronous mechanism won't be noticed.
There are many different queues in Ember, and the fundamental mechanism behind all this is the run loop.