InfoPath: Passing nodes to C# from form rules - xpath

I have just discovered the very useful xdExtension keyword which allows you to execute code directly from a form rule. However any nodes passed into the called function are of type ComObject and there doesn't seem to be a way to cast them into an XPathNavigator or other useful construct from within C#.
Rule condition:
xdExtension:Myfunction(../my:Node)
This should allow me to manipulate the passed node in C#, but instead I just get a ComObject that can't be cast to anything.
Is there any way to pass something that C# can identify as an XPathNode?

Related

What is the name of the design pattern to avoid chained field access?

There is a pattern or term that is used to avoid codes like
myObject.fieldA.fieldB.fieldC
something like this. I forgot what this term is called. Can anyone let me know about it?
It violates the Law of Demeter, which states that code should only access its own local variables, parameters, and instance members.
It could be a case of of feature envy, where a class calls a lot of getters or accesses a lot of data from another class.
If these are really fields, they are poorly encapsulated (i.e., not behind a function), and any change to these fields forces you to modify all code that's using them.
Testing such code becomes hard, as you will have to mock not only fieldA, but also that's fieldB, and in turn that's fieldC.
I think you are trying to create a new object and add certain properties to that object. If that is the case then it's Builder design patten where you seperate the construction and representation.
If you are trying to call a certain field with the above shown code then your design is very poor. An object should store only it's own properties.

Trouble with complex routing rule

I have a lookup table called BlockCustomer. I also have an FTP Adapter that picks up files from multiple customers. I need to be able to determine the customer from the source of the file and do a lookup on the table. If BlockCustomer.Customer1 = 0 then it will send it to it's target, otherwise it will do nothing.
If I could use javascript I would do something like this:
WHEN Lookup(BlockCustomer,HL7.Source.split("/incoming/")[1].split("/")[0]),1) = 0
But obviously I can't. I found $ZSTRIP but I'm not sure if or how it will work. Is this possible or am I going to have to create a custom class?
In Cache we use function $piece if needs to get some parts of string by delimiter. For rule you could use the same function called Piece, with the same arguments. So you conditions should looks like:
Lookup(BlockCustomer,Piece(HL7.Source,"/incoming/",2),1)=0
By the way if you think, that you need some specific functions for you, you can do it by developing it. Just extend the class Ens.Rule.FunctionSet and add a method. And function will appear with the same name. As an example you can see at Ens.Util.FunctionSet class, which contains almost all available functions.

How to navigate to a page inside another class library in Windows Phone 7?

There are a set of common pages that I want to use in multiple projects. Hence, I want to build a class library with those pages. The problem is I am not able to pass objects using NavigationService.Navigate(new Uri("/Common;component/SomeName.xaml", UriKind.Relative)); method.
I know I can pass querystring. What I would like to know is...
Is there any limit to the number of strings you can pass in the querystring?
Is there any length limitation of the querystring?
Or better still,
Is there a better way of passing objects from an application to the pages inside a different class library?
About the question "is there a better way". In addition to the solution you've mentioned some people like to use the app's state to pass parameters between objects. For example:
PhoneApplicationService.Current.State["parameter"] = param;
var parameter = PhoneApplicationService.Current.State["parameter"];
Another option is to use a shared class. With complex objects I find it often easiest to use a static public member in a class which can be accessed from both of the projects.
Note that if you choose to use the query string navigation, some special characters in the query string may cause problems. If you can't control the content of the data which is passed between the pages, the shared class -solution is probably better for you. For example in one of our applications we're passing a web site's name in the query string. There's situations where those names can contain a '&' -character (like H&M) and if it does, the query string will break.
When navigating, if building the query strings gets cumbersome, you may check out the Caliburn.Micro and the Uribuilder class in it. It allows you to navigate with a rather nice (and fluent) syntax:
navigation.UriFor<CandidateDetailsPageViewModel>()
.WithParam(x => x.CandidateId, candidate.Id)
.Navigate();
After navigation, the TryGetValue-method can be rather useful when parsing the parameters:
String parameter;
NavigationContext.QueryString.TryGetValue("Parameter", out parameter)
More details for NavigationContext.QueryString is available from MSDN.
To answer your questions:
No there is no limit to the number of strings you can pass in a qyerystring
I believe the answer to this may be yes. I believe the standard is to have a url of < 2000 characters
For small items I usually just pass a query string to my pages. For more complex cases I have a shared static Domain class that both libraries reference. Then I can just access this variable statically really easily.

Changing workflow IF-conditions from a string runtime

I want to be able to change the condition statement of a WF4 Workflow If-Activtity runtime, where the input comes from some sort of user interface as a string. I have read up on how to change a Workflow dynamically, or how to create Activites from code - the problem comes when I get to the point of assigning the Condition-property to the If-activity class. My source is a string. The constructor does not take a string.
Do I have to convert the string to an Expression<bool> first? How do I do that?
This is the string I want to expose
Note: I realize there may be other ways to accomplish what I want, like (1) create code that alters the XAML of the Workflow instead of the objects, or (2) exposing the entire Workflow editor to the end user. Before I go down that road, I want to know if it is possible to do it my way.
You can use a expression like
new VisualBasicValue<bool>("Person.Gender = \"Male\"")
A warning: The Apply Workflow Changes to Workflows you are pointing to is about WF3 and has no bearing in WF4 whatsoever. With WF4 there is no possibility to dynamically change a running workflow instance. That capability is going to be added in the .NET 4.5 framework.

How Does Queryable.OfType Work?

Important The question is not "What does Queryable.OfType do, it's "how does the code I see there accomplish that?"
Reflecting on Queryable.OfType, I see (after some cleanup):
public static IQueryable<TResult> OfType<TResult>(this IQueryable source)
{
return (IQueryable<TResult>)source.Provider.CreateQuery(
Expression.Call(
null,
((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(
new Type[] { typeof(TResult) }) ,
new Expression[] { source.Expression }));
}
So let me see if I've got this straight:
Use reflection to grab a reference to the current method (OfType).
Make a new method, which is exactly the same, by using MakeGenericMethod to change the type parameter of the current method to, er, exactly the same thing.
The argument to that new method will be not source but source.Expression. Which isn't an IQueryable, but we'll be passing the whole thing to Expression.Call, so that's OK.
Call Expression.Call, passing null as method (weird?) instance and the cloned method as its arguments.
Pass that result to CreateQuery and cast the result, which seems like the sanest part of the whole thing.
Now the effect of this method is to return an expression which tells the provider to omit returning any values where the type is not equal to TResult or one of its subtypes. But I can't see how the steps above actually accomplish this. It seems to be creating an expression representing a method which returns IQueryable<TResult>, and making the body of that method simply the entire source expression, without ever looking at the type. Is it simply expected that an IQueryable provider will just silently not return any records not of the selected type?
So are the steps above incorrect in some way, or am I just not seeing how they result in the behavior observed at runtime?
It's not passing in null as the method - it's passing it in as the "target expression", i.e. what it's calling the method on. This is null because OfType is a static method, so it doesn't need a target.
The point of calling MakeGenericMethod is that GetCurrentMethod() returns the open version, i.e. OfType<> instead of OfType<YourType>.
Queryable.OfType itself isn't meant to contain any of the logic for omitting returning any values. That's up to the LINQ provider. The point of Queryable.OfType is to build up the expression tree to include the call to OfType, so that when the LINQ provider eventually has to convert it into its native format (e.g. SQL) it knows that OfType was called.
This is how Queryable works in general - basically it lets the provider see the whole query expression as an expression tree. That's all it's meant to do - when the provider is asked to translate this into real code, that's where the magic happens.
Queryable couldn't possibly do the work itself - it has no idea what sort of data store the provider represents. How could it come up with the semantics of OfType without knowing whether the data store was SQL, LDAP or something else? I agree it takes a while to get your head round though :)

Resources