I'm writing a bean that extends LifecycleStrategy and during
onContextStart(CamelContext context)
I need to retrieve all the properties that have been loaded in the context. If I call context.getProperties() it returns a map with lenght = 0 (it seams that no properties are loaded) but if i call resolvePropertyPlaceholders("{{one.of.my.properties}}") it resolves correctly.. There is any way to retrieve all the properties key?
ps. my properties are loaded via propertyPlaceholder in camelContext
I had the same problematic and the only way to do it was to read again the property file from the context:
PropertiesComponent pc = (PropertiesComponent) exchange
.getContext()
.getComponent("properties");
// Assume only one property file configured
String location = pc.getLocations()[0];
Properties props = new Properties();
props.load(getClass()
.getClassLoader()
.getResourceAsStream(
StringUtils.substringAfter(location,
":"))); // remove the classpath: if existing
for (String propName : props.stringPropertyNames()) {
if (propName.startsWith("my.word.")) {
endpoints.add(props.getProperty(propName));
}
}
I don't think it is nice way, but for the moment I have no other cleaner solution.
These are two different things.
context.getProperties() is some options you can configure.
The other thing is property placeholder
http://camel.apache.org/using-propertyplaceholder.html
Related
I'm planning to create some pages which display data from an external SQL Server with Orchard CMS. It looks like I need to write a new module to implement this function. Is there any example or idea to implement this requirement?
Yes, you will need to write a new module, which provides a new content part and a content part driver. That driver will be responsible for fetching the data from the external SQL Server, which you will set to a property on the shape you will be returning from your driver. The shape's view will then display your data.
This tutorial will walk you through writing a custom content part: http://docs.orchardproject.net/en/latest/Documentation/Writing-a-content-part/
When you do, make sure not to create the content part Record type, since you will not be storing and loading data from the Orchard database - you want to load data from an external database. These are the steps you should follow:
Create a new module
Create a content part class
Have your part inherit from ContentPart, not ContentPart<TRecord> since there won't be any "TRecord".
Create a content part driver
On the Display method, return a shape by calling the ContentShape method. Make sure to add the SQL data access logic within the lambda. If you do it outside of that lambda, that data access code will be invoked every time the content item using your content part is invoked. Although that sounds as if that is exactly what you want, there's a subtlety here that involves Placement.info, which you can use to determine when your shape will actually be rendered or not. If the placement logic determines that your shape should not be rendered, then you don't want to access your external data for nothing.
Create a Placement.info file to configure the shape's placement (within the context of the content item being rendered).
Create the Razor view for the shape that you return in step 3.2.
Create a Migrations class that will define your custom content part, and any content types to which you want to add your part to. See http://docs.orchardproject.net/en/latest/Documentation/Understanding-data-access/ for more information on how to create migrations.
PS. Instead of implementing your data access code directly in the driver, I recommend you implement that in a separate class. Because you know, separation of concerns and such. You can then inject that service into your driver. To have your service class be registered with the service container, make sure that you define an interface for it, that itself derives from IDependency.
Some sample pseudo code:
Service code:
public interface IMyExternalDataStore : IDependency {
IList<MyExternalDataRecord> GetMyData();
}
public class MyExternalDataStore : IMyExternalDataStore {
public IList<MyExternalDataRecord> GetMyData() {
// Connect to your SQL Server database, perhaps using EF, load the data and return it. Could of course also be simply a DataSet.
}
}
Content Part:
public class MyExternalDataPart : ContentPart {
// Nothing here, unless you want to include some properties here that influence the data that you want to load. If so, you'll also want to implement the Editor methods in your content part driver, but I'm keeping it simple.
}
Content Part Driver:
public class MyExternalDataPartDriver : ContentPartDriver<MyExternalContentPart> {
private readonly IMyExternalDataStore _dataStore;
public MyExternalDataPartDriver(IMyExternalDataStore dataStore) {
_dataStore = dataStore;
}
protected override DriverResult Display(SlideShowProPart part, string displayType, dynamic shapeHelper) {
return ContentShape("Parts_MyExternalData", () => {
// Notice that we're performing the data access here within the lambda (the so called "shape factory method").
var data = _dataStore.GetMyData();
// Notice that I'm creating a property called "MyData"on the shape (which is a dynamic object).
return shapeHelper.Parts_MyExternalData(MyData: data));
}
}
}
Razor view for the Parts_MyExternalData shape:
Filename: Parts.MyExternalData.cshtml
#{
var records = (IList<MyExternalDataRecord>)Model.MyData;
}
<ul>
#foreach(var record in records) {
<li>#record.ToString()</li>
}
</ul>
Placement.info:
<Placement>
<Place Parts_MyExternalData="Content:0"/>
</Placement>
Migrations:
public class Migrations : DataMigrationImpl {
public int Create() {
// Define your content part so that you can attach it to any content type from the UI.
ContentDefinitionManager.AlterPartDefinition("MyExternalDataPart", part => part.Attachable());
// Optionally, define a new content type here programmatically or attach it to an existing type.
return 1;
}
}
I am new to WPF and Prism, but I already learned that you have to register a View in Unity as an object:
Container.RegisterType<Object,MyView>("My.Assembly.MyView");
Still, when I use
var RelativeUriToMyView = new Uri("My.Assembly.MyView",UriKind.Relative);
RegionManager.RequestNavigate(RelativeUriToMyView, RegionName, CallbackResult);
the MyView displays as System.Object, and the CallbackResult contains no Error.
What am I missing? I'm happy to provide more information if needed.
You would want to look at the RegionNavigationContentLoader.cs in the PRISM source code; Here is the code that is loading the view for you.
protected virtual object CreateNewRegionItem(string candidateTargetContract)
{
object newRegionItem;
try
{
newRegionItem = this.serviceLocator.GetInstance<object>(candidateTargetContract);
}
catch (ActivationException e)
{
throw new InvalidOperationException(
string.Format(CultureInfo.CurrentCulture, Resources.CannotCreateNavigationTarget, candidateTargetContract),
e);
}
return newRegionItem;
}
There are several helper methods that take the URI, extract the query string, and create the 'name' used to lookup your view and cast it as an object.
Essentially, the name you are using to associate your concrete class as an object with Unity is the same one you'll need to use when you try to resolve the object with Unity. Here is some pesudocode to explain,
Container.RegisterType<object, ConcreteClass>(typeof(ConcreteClass).FullName);
Locator.GetInstance<object>(UriWithFullName)
If none of this helps, post the RelativeUriToMyView so I can see the contents.
Good luck.
The issue seemed to be caused by registering the view with its FullName (My.Assembly.MyView) instead of its Name (MyView).
Edit:
Changed the question to more accurately reflect the issue.
I want a class (called PremiseServer) in my Mvvm-Light solution (WP7) to subscribe to all property changes for classes that are derived from a base type (SysObject is the base class and it derives from ViewModel).
I have a set of classes derived from SysObject. These classes have various properties on them of differing types (Strings, booleans, ints etc...).
When any property on any of these classes changes I want my PremiseServer instance to see these changes and then make web-service calls to push the data to a server.
I have tried this and it never gets called (which makes sense to me now; because the property that is getting changed is not SysObject, but some property OF the SysObject):
Messenger.Default.Register<PropertyChangedMessage<SysObject>>(this, (action) => {
String location = ((SysObject)action.Sender).Location; // URL to POST to
Debug.WriteLine("PremiseServer PropertyChange - " + action.NewValue.ToString());
});
I also tried the below (registering String messages) and it works, but I don't want to create one of these for each property type:
Messenger.Default.Register<PropertyChangedMessage<String>>(this, (action) => {
String location = ((SysObject)action.Sender).Location; // URL to POST to
Debug.WriteLine("PremiseServer PropertyChange - " + action.NewValue.ToString());
});
I also tried Register<PropertyChangeMessage<Object> thinking I'd see messages for all derived types (I didn't).
What I really want is "Register for all property change messags from any property of objects of class SysObject". How can I do that?
Thanks!
You can register for PropertyChangedMessageBase using the Register method overload that has a boolean flag as the last parameter, and setting this flag to true. Like its name shows, this flag allows you to register for a message type, or all messages deriving from this type.
Note that in the handler, you will need to cast the message to the exact type that you want to handle.
Does it make sense?
Cheers,
Laurent
Be careful about this because everywhere in your app where you invoke RaisePropertyChanged(...) this registered listener will see the PropertyChangedMessageBase.
You may have to do something like:
// this registration ensures that if a broadcast is issued for RaisePropertyChanged the vm will acknowledge it and enable IsDirty.
// NOTE: Do not broadcast from IsDirty or we will get into an endless loop here.
Messenger.Default.Register<PropertyChangedMessageBase>(this, true,
(m) =>
{
if (m.Sender != this) return; // we only listen for property changes on ourself
if (IsStartingUp || IsShuttingDown) return;
if (m.PropertyName != IsDirtyPropertyName && m.PropertyName != IsBusyPropertyName && m.PropertyName != IsStartingUpPropertyName && m.PropertyName != IsShuttingDownPropertyName)
IsDirty = true;
});
In the python app engine docs, I see something called dbReferenceProperty. I can't understand what it is, or how it's used. I'm using the java interface to app engine, so I'm not sure if there's an equivalent.
I'm interested in it because it sounds like some sort of pseudo-join, where we can point a property of a class to some other object's value - something like if we had:
class User {
private String mPhotoUrl;
private String mPhone;
private String mState;
private String mCountry;
.. etc ..
}
class UserLite {
#ReferenceProperty User.mPhotoUrl;
private String mPhotoUrl;
}
then if we had to update a User object's mPhotoUrl value, the change would somehow propagate out to all UserLite instances referencing it, rather than having to update every UserLite object instance manually,
Thanks
A db.ReferenceProperty simply holds the key of another datastore entity, which is automatically fetched from the datastore when the property is used.
There's some additional magic where the entity that is referenced has access to a query for entities of type Foo that reference it in the special attribute foo_set.
The Java datastore API instead has owned relationships, which serve the same purpose.
I've got a CustomersModule.cs with the following Initialize() method:
public void Initialize()
{
container.RegisterType<ICustomersRepository, CustomersRepository>(new ContainerControlledLifetimeManager());
CustomersPresenter customersPresenter = this.container.Resolve<CustomersPresenter>();
}
The class I resolve from the container looks like this:
class CustomersPresenter
{
private CustomersView view;
private ICustomersRepository customersRespository;
public CustomersPresenter(CustomersView view,
ICustomersRepository customersRepository,
TestWhatever testWhatever)
{
this.view = view;
this.customersRespository = customersRepository;
}
}
The TestWhatever class is just a dummy class I created:
public class TestWhatever
{
public string Title { get; set; }
public TestWhatever()
{
Title = "this is the title";
}
}
Yet the container happily resolves CustomersPresenter even though I never registered it, and also the container somehow finds TestWhatever, instantiates it, and injects it into CustomersPresenter.
I was quite surprised to realize this since I couldn't find anywhere in the Prism documentation which explicitly stated that the container was so automatic.
So this is great, but it what else is the container doing that I don't know about i.e. what else can it do that I don't know about? For example, can I inject classes from other modules and if the modules happen to be loaded the container will inject them, and if not, it will inject a null?
There is nothing magical going on. You are specifying concrete types, so naturally they are resolvable, because if we have the Type object, we can call a constructor on it.
class Fred { };
Fred f1 = new Fred();
Type t = typeof(Fred);
Fred f2 = (Fred)t.GetConstructor(Type.EmptyTypes).Invoke(null);
The last line above is effectively what happens, the type t having been found by using typeof on the type parameter you give to Resolve.
If the type cannot be constructed by new (because it's in some unknown separate codebase) then you wouldn't be able to give it as a type parameter to Resolve.
In the second case, it is constructor injection, but it's still a known concrete constructable type. Via reflection, the Unity framework can get an array of all the Types of the parameters to the constructor. The type TestWhatever is constructable, so there is no ambiguity or difficulty over what to construct.
As to your concern about separate modules (assemblies), if you move TestWhatever to another assembly, that will not change the lines of code you've written; it will just mean that you have to add a reference to the other assembly to get this one to build. And then TestWhatever is still an unambiguously refeferenced constructable type, so it can be constructed by Unity.
In other words, if you can refer to the type in code, you can get a Type object, and so at runtime it will be directly constructable.
Response to comment:
If you delete the class TestWhatever, you will get a compile-time error, because you refer to that type in your code. So it won't be possible to get a runtime by doing that.
The decoupling is still in effect in this arrangement, because you could register a specific instance of TestWhatever, so every call to Resolve<TestWhatever>() will get the same instance, rather than constructing a new one.
The reason this works is because Unity is designed for it. When you Resolve with a concrete type, Unity looks to see if it can resolve from the container. If it cannot, then it just goes and instantiates the type resolving it's dependencies. It's really quite simple.