ConstructorArguments without magic strings - ninject

If I want to specify a constructor argument I need to specify the argument name as string. Unfortunately, this is not very refactoring friendly. Is there any way to get around this limitation?

See http://www.planetgeek.ch/2011/05/28/ninject-constructor-selection-preview/ . The next release of Ninject will support to type safely define constructor arguments.

Do:
string s = "my string"
kernel.Bind<IMyInterface>().ToConstructor(x => new MyObject(s));
where MyObject implements IMyInterface.

Related

Why do I have to store the result of a function in a variable?

Is it because some functions will change the object and some don't so you have to store the returned value in a variable? I'm sure there's a better way to ask the question, but I hope that makes sense.
Example case: Why doesn't thisString stay capitalized? What happens to the output of the toUpperCase() function when I call it on thisString? Is there a name for this behavior?
var thisString: String = "this string"
var thatString: String = "that string"
thisString.toUpperCase()
thatString = thatString.toUpperCase()
println(thisString)
println(thatString)
which prints:
this string
THAT STRING
By convention if a function starts with the word to or a past participle, it always returns a new object and does not mutate the object it's called on. But that's not exclusively true. Functions that begin with a verb may or may not mutate the object, so you have to check the documentation to know for sure.
A mutable object might still have functions that return new objects. You have to check the documentation for the function you call.
For a function that returns a new object, if you don't do anything with the returned result or store it in a variable, it is lost to the garbage collector and you can never retrieve it.
String is an immutable class, so none of the functions you call on it will ever modify the original object. Immutable classes are generally less error-prone to work with because you can't accidentally modify an instance that's still being used somewhere else.
All the primitives are also immutable. If all the properties of a class are read-only vals and all the class types they reference are also immutable classes, then the class is immutable.
If you want an mutable alternative to String, you can use StringBuilder, StringBuffer, CharArray, or MutableList<Char>, depending on your needs. They all have different pros and cons.
Why doesn't thisString stay capitalized?
Because that's how the function was coded (emphasis mine):
"Returns a copy of this string converted to upper case using the rules of the default locale."
What happens to the output of the toUpperCase() function when I call it on thisString?
Nothing. If you don't assign it to a variable (save a reference to it) it's discarded.
Is there a name for this behavior?
AFAIK, this is simply "ignoring the return value".
Hope that helps.

How to name a function that creates fixpoint results on its input?

I have a function that decorates a string. If the decorated string is again fed to the function, it is guaranteed not to change. How is the standard naming convention for such a function? I'll probably create a namespace because I need to have a few of those functions.
I've come up with:
repetition_safe.decorate(me);
fixpoint_gen.decorate(me);
one_time_effect.decorate(me);
but I don't really like any of these.
How would you name the namespace or function?
How about:
StringDecorator.MakeImmutable(input);
I think "MakeImmutable" is better than "Decorate" as the later is ambiguous i.e. a user reading the code won't know what "decorate" does, whereas "makeImmutable" will inform the user that this function will make the input string immutable/non-changable.

Test method existence on Objects

I have a cell array of Matlab objects, something like:
objs = {Object1(), Object2(), Object3()};
These objects are all of different types. Some of them will have a method, let's call it myMethod(). I want to do something like:
for o = objs
if hasMethod(o, 'myMethod()')
o.myMethod();
end
end
and my difficulty is that I don't know how to do hasMethod - exist doesn't seem helpful here.
I could use a try - catch, but I'd rather do something neater. Is there a way to do this? Should I just change my design instead?
Another option is to use the meta class.
obmeta = metaclass(ob);
methodNames = cellfun(#(x){x.Name},obmeta.Methods);
You can also get additional information from obmeta.Methods like
Amount of input/output parameters.
Access type
In which class the method is defined.
Also, metaclass can be constructed from the name of the class, without an instance, which can be an advantage in some situations.
Ah, found it. Not very exciting - you can get a list of methods with the methods command. So to check if an object has a method,
if any(strcmp(methods(o), 'myMethod'))
o.myMethod();
end
Very close! If you had written the function name a bit differently you would've stumbled upon the following built-in:
if ismethod(o, 'myMethod')
o.myMethod();
end
Documentation: ismethod.
Why would you want to do that? You'd better have a good reason :p
Better make them inherit a general function from a superclass. Then you can just call that function for all of them, instead of looking up which class it is/checking if a function exists and then calling a function depending on the result (which is imo not very OO)
One simple option is to use the function EXIST (along with the function CLASS) to check if the method exists for the given class:
if exist(['#' class(o) '/myMethod'])
o.myMethod();
end
Another option is to use the function WHICH to perform the check like this:
if ~isempty(which([class(o) '/myMethod']))
o.myMethod();
end

Ninject Cascading Constructor Arguments

I have a type IRoleRepository which accepts a constructor argument "database" which accepts a type of IDbRepository which itself takes a constructor argument "ConnectionStringName". I have a dependency resolver which has a GetService method and while the following code works I was hoping there would be better way to do this at Bind time vs at Get time with Ninject 3.0. Note I may have multiple IDBRepository instances each with their own "ConnectionStringName".
_repository = EngineContext.Current.GetService<IRoleRepository>(
new ConstructorArgument("database",
EngineContext.Current.GetService<IDbRepository>(
new ConstructorArgument(SystemConstants.ConnectionStringName, SystemConstants.ConfigurationDatabase))));
You can use WithConstructorArgument to specify the constructor arguments together with the binding.
kernel.Bind<IDbRepository>().To<DbRepository>()
.WithConstructorArgument(
SystemConstants.ConnectionStringName,
SystemConstants.ConfigurationDatabase);
or use ToConstructor()
kernel.Bind<IDbRepository>().ToConstructor(
x => new DbRepository(
SystemConstants.ConfigurationDatabase,
x.Inject<ISomeOtherDependency>())
OK I believe I found what I wanted:
By using this at Bind Time:
Bind<IDbRepository>().To<SqlServerRepository>()
.WhenInjectedInto<IRoleRepository>()
.WithConstructorArgument(SystemConstants.ConnectionStringName, SystemConstants.ConfigurationDatabase);
This allows me to use this at Get time:
_repository = EngineContext.Current.GetService<IRoleRepository>();
This of course means I can now vary the constructor argument for IDbRepository based upon the more specific repository which the IDbRepository is being injected. eg:
Bind<IDbRepository>().To<SqlServerRepository>()
.WhenInjectedInto<ITimerJobStore>()
.WithConstructorArgument(SystemConstants.ConnectionStringName, SystemConstants.ConfigurationDatabase);
Bind<ITimerJobStore>().To<TimerJobSqlStore>();

How Do I Create Something 'OF' a Variable's Type?

I have some code like:
Lookup(Of String)("Testing")
Lookup(Of Integer)("Testing")
And both of those Lookups work great. What I'm trying to is call the appropriate LookUp based on the type of another variable. Something that would look like...
Lookup(Of GetType(MyStringVariable))("Testing")
I've tried to Google this but I'm having a hard time coming up with an appropriate search. Can anyone tell me how to do what I want?
You do not specify the full signature for the method that you're calling, but my psychic powers tell me that it is this:
Function Lookup(Of T)(key As String) As T
And you want to avoid having to repeat Integer twice as in the example below:
Dim x As Integer
x = Lookup(Of Integer)("foo");
The problem is that type parameters are only deduced when they're used in argument context, but never in return value context. So, you need a helper function with a ByRef argument to do the trick:
Sub Lookup(Of T)(key As String, ByRef result As T)
T = Lookup(Of T)(key)
End Sub
With that, you can write:
Dim x As Integer
Lookup("foo", x);
One solution to this is to use reflection. See this question for details.
You can't use a dynamic type unless you do runtime compiling, which of course is really inefficient.
Although generics allows you to use different types, the type still has to be known at compile time so that the compiler can generate the specific code for that type.
This is not the way to go. You should ask about what problem you are trying to solve, instead of asking about the way that you think that it should be solved. Even if it might be possible to do something close to what you are asking, it's most likely that the best solution is something completely different.
The VB.NET compiler in VS2008 actually uses type-inference. That means if you are using a generic method, and one of the parameters is of the generic type, then you don't need to specify the generic type in your call.
Take the following definition...
Function DoSomething(Of T)(Target As T) As Boolean
If you call it with a strongly-typed String for Target, and don't specify the generic parameter, it will infer T as String.
If you call it with a strongly-typed Integer for Target, and don't specify the generic parameter, it will infer T as Integer.
So you could call this function as follows:
Dim myResult As Boolean = DoSomething("my new string")
And it will automatically infer the type of T as String.
EDIT:
NOTE: This works for single or multiple generic parameters.
NOTE: This works also for variables in the argument list, not just literals.