Unity Container passing runtime constructor parameters - unity-container

I have two constructors, the first works fine as follows:
public ESite(Func<IOrg> unityOrgFactory)
{
this.OrFactory = unityOrgFactory;
this.Kid = Guid.Empty;
}
_IoC.RegisterType<IESite, ESite>();
IESite eSite = boClass.IoC.Resolve<IESite>();
Now, I need to pass in a key at runtime so I add a constructor as usual:
public ESite(Func<IOrg> unityOrgFactory, Guid kid)
{
this.OrFactory = unityOrgFactory;
this.Kid = kid;
}
Syntax for this registration and resolve usage? I've tried several InjectionConstructor variants but can't get it right...I'm missing something. After several search-and-try rounds, time to ask! I have read several posts on related topics...
Thanks for tips!
GG

A reasonable workaround (not necessarily the best answer) is to disencumber the constructor by moving the injected parameters to an InjectionMethod
Register:
// Use InjectionMethod Initializer to free up constructors. http://msdn.microsoft.com/en-us/library/ff953186(v=pandp.50).aspx new InjectionMethod("Initialize", typeof(Database), "CustomerServices")
_IoC.RegisterType<IESite, ESite>(
new InjectionMethod("Initialize", typeof(Func<IOrg>))
);
Use:
//http://msdn.microsoft.com/en-us/library/ff953186(v=pandp.50).aspx
[InjectionMethod]
public void Initialize(Func<IOrg> unityOrgFactory)

Related

Can I mock the values of a List<Microsoft.Bing.Speech.RecognitionPhrase> just like in the VS debugger?

When writing Unit Tests for a function that is consuming a List<Microsoft.Bing.Speech.RecognitionPhrase> I face the following error:
Invalid setup on a non-virtual (overridable in VB) member: x =>
x.Confidence
After reading here, I get that this is because the property is not virtual. I have been reading in the site about interfaces, wrappers, virtuals...but with no success.
I have access to RecognitionPhrase [from metadata] and it has public Confidence Confidence { get; } so there's no set here. I have tried to create a public interface IRecognitionPhrase and a public class RecognitionPhrase : IRecognitionPhrase, but then in the final casting it says that it cannot cast my RecognitionPhrase to Microsoft.Bing.Speech.RecognitionPhrase.
I have read something about reflection but it seems to work with private setters rather than with no setters.
I'm out of ideas now. Any directions are much appreciated (and of course if someone has already mocked List<Microsoft.Bing.Speech.RecognitionPhrase> please comment how did you do it) Thanks
I'm open to employing any other testing framework.
I've finally solved it using reflection...but not reflection of the Mock (which was throwing an exception)
//var mockFrase = new Mock<RecognitionPhrase>();
//PropertyInfo propertyInfo = mockFrase.GetType().GetProperty("Confidence");
//propertyInfo.SetValue(mockFrase, Confidence.High);
Instead, using reflection on the real object solved the problem for me:
var frase = new RecognitionPhrase();
PropertyInfo propertyInfo = frase.GetType().GetProperty("Confidence");
propertyInfo.SetValue(frase, Confidence.High);

Can somebody please explain this common binding pitfall to me? (using the wrong bindable event name)

I refer to this site link text
Using the wrong event name in the
[Bindable] tag can cause your
application to not bind your property,
and you will not even know why. When
you use the [Bindable] tag with a
custom name, the example below looks
like a good idea:
public static const EVENT_CHANGED_CONST:String = "eventChangedConst";
private var _number:Number = 0;
[Bindable(event=EVENT_CHANGED_CONST)]
public function get number():Number
{
return _number;
}
public function set number(value:Number) : void
{
_number = value;
dispatchEvent(new Event(EVENT_CHANGED_CONST));
}
The code above assigns a static
property to the event name, and then
uses the same assignment to dispatch
the event. However, when the value
changes, the binding does not appear
to work. The reason is that the event
name will be EVENT_CHANGED_CONST and
not the value of the variable.
The code should have been written as
follows:
public static const EVENT_CHANGED_CONST:String = "eventChangedConst";
private var _number:Number = 0;
[Bindable(event="eventChangedConst")]
public function get number():Number
{
return _number;
}
public function set number(value:Number) : void
{
_number = value;
dispatchEvent(new Event(EVENT_CHANGED_CONST));
}
I agree, the wrong example does look like a good idea and I would do it that way because I think it's the right way and avoids the possibility of a typing error. Why is the name of the constant used instead of it's value? Surely this can't be right?
I appreciate your insights
Because the standard Flex compiler isn't that clever at times... and I feel your pain! I've complained about this exact problem more than a few times.
If I remember correctly, it's because the compiler does multiple passes. One of the early passes changes the Metadata into AS code. At this point in the compiler it hasn't parsed the rest of the AS code, so its not capable of parsing Constants or references to static variables in other files.
The only thing I can suggest is sign up to the Adobe JIRA, vote for the bug, and hope that the compiler fixes in 4.5 bring some relief.

Can I create a column of nvarchar(MAX) using FluentMigrator?

Using FluentMigrator, the default creation of a Column using .AsString() results in an nvarchar(255). Is there a simple way (before I modify the FluentMigrator code) to create a column of type nvarchar(MAX)?
You could create an extension method to wrap .AsString(Int32.MaxValue) within .AsMaxString()
e.g.
internal static class MigratorExtensions
{
public static ICreateTableColumnOptionOrWithColumnSyntax AsMaxString(this ICreateTableColumnAsTypeSyntax createTableColumnAsTypeSyntax)
{
return createTableColumnAsTypeSyntax.AsString(int.MaxValue);
}
}
OK, I found it. Basically, use .AsString(Int32.MaxValue). Pity there's not a .AsMaxString() method, but I guess it's easy enough to put in...
You can use AsCustom("nvarchar(max)") and pack it to extension
If you often create columns/tables with the same settings or groups of columns, you should be creating extension methods for your migrations!
For example, nearly every one of my tables has CreatedAt and UpdatedAt DateTime columns, so I whipped up a little extension method so I can say:
Create.Table("Foos").
WithColumn("a").
WithTimestamps();
I think I created the Extension method properly ... I know it works, but FluentMigrator has a LOT of interfaces ... here it is:
public static class MigrationExtensions {
public static ICreateTableWithColumnSyntax WithTimestamps(this ICreateTableWithColumnSyntax root) {
return root.
WithColumn("CreatedAt").AsDateTime().NotNullable().
WithColumn("UpdatedAt").AsDateTime().NotNullable();
}
}
Similarly, nearly every one of my tables has an int primary key called 'Id', so I think I'm going to add Table.CreateWithId("Foos") to always add that Id for me. Not sure ... I actually just started using FluentMigrator today, but you should always be refactoring when possible!
NOTE: If you do make helper/extension methods for your migrations, you should never ever ever change what those methods do. If you do, someone could try running your migrations and things could explode because the helper methods you used to create Migration #1 works differently now than they did earlier.
Here is the code for creating columns incase it helps you create helper methods: https://github.com/schambers/fluentmigrator/blob/master/src/FluentMigrator/Builders/Create/Column/CreateColumnExpressionBuilder.cs
How about extending like this:
public static class StringMaxMigratorExtensions
{
public static ICreateTableColumnOptionOrWithColumnSyntax AsStringMax(this ICreateTableColumnAsTypeSyntax createTableColumnAsTypeSyntax)
{
return createTableColumnAsTypeSyntax.AsCustom("nvarchar(max)");
}
public static IAlterColumnOptionSyntax AsStringMax(this IAlterColumnAsTypeSyntax alterColumnAsTypeSyntax)
{
return alterColumnAsTypeSyntax.AsCustom("nvarchar(max)");
}
}

strongly typed sessions in asp.net

Pardon me if this question has already been asked. HttpContext.Current.Session["key"] returns an object and we would have to cast it to that particular Type before we could use it. I was looking at various implementations of typed sessions
http://www.codeproject.com/KB/aspnet/typedsessionstate.aspx
http://weblogs.asp.net/cstewart/archive/2008/01/09/strongly-typed-session-in-asp-net.aspx
http://geekswithblogs.net/dlussier/archive/2007/12/24/117961.aspx
and I felt that we needed to add some more code (correct me if I was wrong) to the SessionManager if we wanted to add a new Type of object into session, either as a method or as a separate wrapper. I thought we could use generics
public static class SessionManager<T> where T:class
{
public void SetSession(string key,object objToStore)
{
HttpContext.Current.Session[key] = objToStore;
}
public T GetSession(string key)
{
return HttpContext.Current.Session[key] as T;
}
}
Is there any inherent advantage in
using
SessionManager<ClassType>.GetSession("sessionString")
than using
HttpContext.Current.Session["sessionString"] as ClassType
I was also thinking it would be nice
to have something like
SessionManager["sessionString"] = objToStoreInSession,
but found that a static class cannot have an indexer. Is there any other way to achieve this ?
My thought was create a SessionObject which would store the Type and the object, then add this object to Session (using a SessionManager), with the key. When retrieving, cast all objects to SessionObject ,get the type (say t) and the Object (say obj) and cast obj as t and return it.
public class SessionObject { public Type type {get;set;} public Object obj{get;set;} }
this would not work as well (as the return signature would be the same, but the return types will be different).
Is there any other elegant way of saving/retrieving objects in session in a more type safe way
For a very clean, maintainable, and slick way of dealing with Session, look at this post. You'll be surprised how simple it can be.
A downside of the technique is that consuming code needs to be aware of what keys to use for storage and retrieval. This can be error prone, as the key needs to be exactly correct, or else you risk storing in the wrong place, or getting a null value back.
I actually use the strong-typed variation, since I know what I need to have in the session, and can thus set up the wrapping class to suit. I've rather have the extra code in the session class, and not have to worry about the key strings anywhere else.
You can simply use a singleton pattern for your session object. That way you can model your entire session from a single composite structure object. This post refers to what I'm talking about and discusses the Session object as a weakly typed object: http://allthingscs.blogspot.com/2011/03/documenting-software-architectural.html
Actually, if you were looking to type objects, place the type at the method level like:
public T GetValue<T>(string sessionKey)
{
}
Class level is more if you have the same object in session, but session can expand to multiple types. I don't know that I would worry about controlling the session; I would just let it do what it's done for a while, and simply provide a means to extract and save information in a more strongly-typed fashion (at least to the consumer).
Yes, indexes wouldn't work; you could create it as an instance instead, and make it static by:
public class SessionManager
{
private static SessionManager _instance = null;
public static SessionManager Create()
{
if (_instance != null)
return _instance;
//Should use a lock when creating the instance
//create object for _instance
return _instance;
}
public object this[string key] { get { .. } }
}
And so this is the static factory implementation, but it also maintains a single point of contact via a static reference to the session manager class internally. Each method in sessionmanager could wrap the existing ASP.NET session, or use your own internal storage.
I posted a solution on the StackOverflow question is it a good idea to create an enum for the key names of session values?
I think it is really slick and contains very little code to make it happen. It needs .NET 4.5 to be the slickest, but is still possible with older versions.
It allows:
int myInt = SessionVars.MyInt;
SessionVars.MyInt = 3;
to work exactly like:
int myInt = (int)Session["MyInt"];
Session["MyInt"] = 3;

Flex: AMF and Enum Singletons – can they play well together?

I'm using Python+PyAMF to talk back and forth with Flex clients, but I've run into a problem with the psudo-Enum-Singletons I'm using:
class Type {
public static const EMPTY:Type = new Type("empty");
public static const FULL:Type = new Type("full");
...
}
When I'm using locally created instances, everything is peachy:
if (someInstance.type == Type.EMPTY) { /* do things */ }
But, if 'someInstance' has come from the Python code, it's instance of 'type' obviously won't be either Type.EMPTY or Type.FULL.
So, what's the best way to make my code work?
Is there some way I can control AMF's deserialization, so when it loads a remote Type, the correct transformation will be called? Or should I just bite the bullet and compare Types using something other than ==? Or could I somehow trick the == type cohesion into doing what I want?
Edit: Alternately, does Flex's remoting suite provide any hooks which run after an instance has been deserialized, so I could perform a conversion then?
Random thought: Maybe you could create a member function on Type that will return the canonical version that matches it?
Something like:
class Type {
public static const EMPTY:Type = new Type("empty");
public static const FULL:Type = new Type("full");
...
// I'm assuming this is where that string passed
// in to the constructor goes, and that it's unique.
private var _typeName:String;
public function get canonical():Type {
switch(this._typeName) {
case "empty": return EMPTY;
case "full": return FULL;
/*...*/
}
}
}
As long as you know which values come from python you would just convert them initially:
var fromPython:Type = /*...*/
var t:Type = fromPython.canonical;
then use t after that.
If you can't tell when things come from python and when they're from AS3 then it would get pretty messy, but if you have an isolation layer between the AS and python code you could just make sure you do the conversion there.
It's not as clean as if you could control the deserialization, but as long as you've got a good isolation layer it should work.

Resources