What can be used as a NHibernate QueryOver alias? - queryover

I know so far that a local variable or a local property can be used as an alias like so
ClassA _aliasA;
_session.QueryOver(x => x.ClassA, () => _aliasA);
or
ClassA AliasA { get; set; }
_session.QueryOver(x => x.ClassA, () => AliasA);
I want to know what other options are possible. Like, are properties of an external class a valid option?
class ClassGenericAliases
{
ClassA Class { get; set; }
}
_session.QueryOver(x => x.ClassA, () => ClassGenericAliases.ClassA);
Can statics be used as aliases?
Are there other options for declaring aliases?

I would recommend never using anything for an Alias outside of the scope of the method that uses the alias.
QueryOver is a strongly typed version of Criteria, in Criteria an alias was a string value.
IList cats = sess.CreateCriteria(typeof(Cat))
.CreateAlias("Kittens", "kt")
.CreateAlias("Mate", "mt")
.Add( Expression.EqProperty("kt.Name", "mt.Name") )
.List();
But now it needs to assign the alias to a variable so we just create one for it:
Cat catAlias = null;
Kitten kittenAlias = null;
IQueryOver<Cat,Cat> catQuery =
session.QueryOver<Cat>(() => catAlias)
.JoinAlias(() => catAlias.Kittens, () => kittenAlias)
.Where(() => catAlias.Age > 5)
.And(() => kittenAlias.Name == "Tiddles");
From NHForge documentation, it says the following:
http://nhibernate.info/doc/nh/en/index.html#queryqueryover-aliases
15.5. Aliases
In the traditional ICriteria interface aliases are assigned using
'magic strings', however their value does not correspond to a name in
the object domain. For example, when an alias is assigned using
.CreateAlias("Kitten", "kittenAlias"), the string "kittenAlias" does
not correspond to a property or class in the domain.
In QueryOver, aliases are assigned using an empty variable. The
variable can be declared anywhere (but should be null at runtime). The
compiler can then check the syntax against the variable is used
correctly, but at runtime the variable is not evaluated (it's just
used as a placeholder for the alias).
Each Lambda Expression function in QueryOver has a corresponding
overload to allow use of aliases, and a .JoinAlias function to
traverse associations using aliases without creating a sub-QueryOver.
So stick to just using a variable in the scope of the method.

I needed to solve a similar issue and decided on an alias naming convention. Then where ever you needed to reuse the alias you can check for it using GetCriteriaByAlias() and add it if it is not there.
Being able to reuse the alias is very handy if you have different select projections. This method is still problematic if someone disregards naming conventions, but then your unit tests should pick that up.
Project aProject = null;
if (root.UnderlyingCriteria.GetCriteriaByAlias("aProject") == null)
root.JoinAlias(i => i.Project, () => aProject);

Related

How can I set the value of a protected var in a mock test (CakePHP)

I want to test a Shell that calls an API. The Shell has a function that sets the value for a protected var protected $_credential = [];
class ImportShell extends AppShell
{
protected $_credential = [];
public function sales() {
$credential = $this->Credential->find('first', [
'conditions' => [
'Credential.id' => $this->args[0]
]
]);
$this->_credential = $credential;
}
}
It uses the values in $this->args to find a Table entry and write that result into $_credential
How can I access/change $_credential in my test when I use it like this?
$ImportShell = $this->getMockBuilder('ImportShell')
->setMethods(array('find'))
->getMock();
$ImportShell->sales();
Also how can I access/change $this->args?
Use reflections
Reflections provide a mechanism to modify and interrogate code, and has a specific function to set a property value. The syntax is a little unwheildy but this allows you to modify the accessibility and value of class properties (and functions). Something like this would do what you want:
$class = new ReflectionClass("ImportShell");
$property = $class->getProperty("_credential");
$property->setAccessible(true);
$ImportShell = $this->getMockBuilder('ImportShell')
->setMethods(array('find'))
->getMock();
$ImportShell->_credential = ['stuff'];
There's a plugin for that
The Friends Of Cake Test Utilities plugin simplifies the syntax to achieve the same thing. The syntax using this plugin would be:
$this->setProtectedProperty('_credential', ['stuff'], $ImportShell);
Is it really necessary though?
args is a public property. Instead of manipulating a protected property, it is possible to simply set the public property that is used to populate it before calling the test function.
$ImportShell = $this->getMockBuilder('ImportShell')
->setMethods(array('find'))
->getMock();
$ImportShell->args = ['stuff'];
$ImportShell->sales();
Though given the way the question is phrased, it'd probably make more sense to mock the Credential model and add an expectation that it'll be called, and return what you want it to.

Access one specific object from class name?

I want to access a specific object with the class name. This object may change, so it is not a singleton.
Like:
MyClass.actualView
or
MyClass.actualView()
Since I get class var are not yet supported as an error, any good short ways in your mind?
I used a global variable and a calculated type property. Only the constant type property are not supported yet.
private var globalVar: MyClass? = nil
class MyClass {
internal class var sharedInstance : MyClass {
get {
return globalVar
set {
globalVar = newValue
}
}
}
Before using it, it must be set from any of the instances:
MyClass.sharedInstance = self
Now I could set and get the type property like I could in every other language, until Apple makes it easier and supports constant type properties.
I can get the sharedInstance from anywhere inside the project (even accessible from Objective-C, when you add #objc before the internal-keyword
Swift:
MyClass.sharedInstance
Objective-C:
[MyClass sharedInstance];

ApiTransformer for parametrized, unavailable type

I'm using Objectify and wish to have its Key<> type passed around in my API. I've created an ApiTransformer, but my questions is where to declare it, since the serialized Key<> class is not available, hence I cannot declare its transformer as a class annotation. I tried declaring it in the #Api annotation, but it doesn't work, I still get the error:
There was a problem generating the API metadata for your Cloud Endpoints classes: java.lang.IllegalArgumentException: Parameterized type com.googlecode.objectify.Key<[my package].User> not supported.
The ApiTransformer looks like:
public class KeyTransformer implements Transformer<Key<?>, String> {
public String transformTo(Key<?> in) {
return in.getString();
}
public Key<?> transformFrom(String in) {
return Key.valueOf(in);
}
}
And in my #Api I have:
#Api(name = "users", version = "v1",transformers = {KeyTransformer.class})
Unfortunately you can't. As you said you need to declare it on the Key class, your only chances to make this work are either.
1) Recompile the Key class for objectify with the #transformer annotation.
2) Extend the Key class with your own implementation and define the transformer there.
I don't really like any of those options so the way i usually resolve this is to hide the key object getter (by using #ApiResourceProperty(ignored=AnnotationBoolean.TRUE)) and only expose the id from that key.
That way you get a Endpoints frendly object, the only downside is you'll have to reconstitute the key using Key.create(YourClass.class, longId) manually whenever you need it.
You can add transforms to 3rd party classes by listing the transform in #Api annotation. I'm not dead sure it'll work parameterized class, but I don't see why not.
https://cloud.google.com/appengine/docs/java/endpoints/javadoc/com/google/api/server/spi/config/Api#transformers()

What does static refer to being "stuck" to?

I'm trying to give myself a mapped idea of the word static (using my current noun definition of static, not having a good understanding of the adjective definition), but it would seem that non-static variables and methods actually are "stuck" (or better said referencing/referring) to objects/instances. So what is the terminology static actually describing about the declared methods/variables?
The words "static" and "dynamic" are frequently used as opposites in programming terminology.
Something that is dynamic is something that changes; in the context of a class, it is something that takes on different values or behaviors with each instance (object).
Something that is static does not change; it is in stasis. So a static variable of a class does not take on different values with each instance.
Static electricity doesn't move; it is stuck in one place, on your socks. Dynamic electricity, in motion in a wire, can do much more powerful things.
I think this question here provides a very detailed answer: What is "static"?
The concept of static has to do with whether something is part of a class or an object (instance).
In the case of the main method which is declared as static, it says that the main method is an class method -- a method that is part of a class, not part of an object. This means that another class could call a class method of another class, by referring to the ClassName.method. For example, invoking the run method of MyClass would be accomplished by:
MyClass.main(new String[]{"parameter1", "parameter2"});
On the other hand, a method or field without the static modifier means that it is part of an object (or also called "instance") and not a part of a class. It is referred to by the name of the specific object to which the method or field belongs to, rather than the class name:
MyClass c1 = new MyClass();
c1.getInfo() // "getInfo" is an instance method of the object "c1"
As each instance could have different values, the values of a method or field with the same name in different objects don't necessarily have to be the same:
MyClass c1 = getAnotherInstance();
MyClass c2 = getAnotherInstance();
c1.value // The field "value" for "c1" contains 10.
c2.value // The field "value" for "c2" contains 12.
// Because "c1" and "c2" are different instances, and
// "value" is an instance field, they can contain different
// values.
Combining the two concepts of instance and class variables. Let's say we declare a new class which contains both instance and class variables and methods:
class AnotherClass {
private int instanceVariable;
private static int classVariable = 42;
public int getInstanceVariable() {
return instanceVariable;
}
public static int getClassVariable() {
return classVariable;
}
public AnotherClass(int i) {
instanceVariable = i;
}
}
The above class has an instance variable instanceVariable, and a class variable classVariable which is declared with a static modifier. Similarly, there is a instance and class method to retrieve the values.
The constructor for the instance takes a value to assign to the instance variable as the argument. The class variable is initialized to be 42 and never changed.
Let's actually use the above class and see what happens:
AnotherClass ac1 = new AnotherClass(10);
ac1.getInstanceVariable(); // Returns "10"
AnotherClass.getClassVariable(); // Returns "42"
Notice the different ways the class and instance methods are called. The way they refer to the class by the name AnotherClass, or the instance by the name ac1. Let's go further and see the behavioral differences of the methods:
AnotherClass ac1 = new AnotherClass(10);
AnotherClass ac2 = new AnotherClass(20);
ac1.getInstanceVariable(); // Returns "10"
AnotherClass.getClassVariable(); // Returns "42"
ac2.getInstanceVariable(); // Returns "20"
AnotherClass.getClassVariable(); // Returns "42"
As can be seen, an instance variable is one that is held by an object (or "instance"), therefore unique to that particular instance, which in this example is the objects referred to by ac1 and ac2.
A class variable on the other hand is only unique to that entire class. To get this point across even better, let's add a new method to the AnotherClass:
public int getClassVariableFromInstance() {
return classVariable;
}
Then, run the following:
AnotherClass ac1 = new AnotherClass(10);
AnotherClass ac2 = new AnotherClass(20);
ac1.getInstanceVariable(); // Returns "10"
ac1.getClassVariableFromInstance(); // Returns "42"
ac2.getInstanceVariable(); // Returns "20"
ac2.getClassVariableFromInstance(); // Returns "42"
Although getClassVariableFromInstance is an instance method, as can be seen by being invoked by referring to the instances ac1 and ac2, they both return the same value, 42. This is because in both instance methods, they refer to the class method classVariable which is unique to the class, not to the instance -- there is only a single copy of classVariable for the class AnotherClass.
I hope that some what clarifies what the static modifier is used for.
The Java Tutorials from Sun has a section called Understanding Instance and Class Members, which also goes into the two types of variables and methods.

Can someone explain the magic going on in Prism's resolve<> method?

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.

Resources