I have a solution that works, but for educational purposes I want to understand if there is a better/cleaner/right way to do it.
Problem: In my "client" app I have a dictionary Dictionary<String, PremiseObject> where the key (String) is a immutable URL to a resource (it's actually a REST URL). PremiseObject is the base type of a whole set of derived classes; thus the Dictionary actually contains a family of classes all derived from PremiseObject.
A key requirement is I want to try to 'guarantee' that no PremiseObjects get created OUTSIDE of the dictionary.
Solution: I have the following function for getting a object out of the dictionary. It either accesses the existing instance, or if it does not exist creates it:
public PremiseObject GetOrCreateServerObject(string premiseObjectType, string location)
{
PremiseObject po = null;
if (!premiseObjects.TryGetValue(location, out po))
{
string classname;
// Create an instance of the right PremiseObject derived class:
po = // gobbly-gook that is not relevant to this question.
premiseObjects.Add(location, po);
}
else
{
Debug.WriteLine("Already exists: {0}", location);
}
return po;
}
Callers do this:
DoorSensor door =
(DoorSensor)server.GetOrCreateServerObject("DoorSensor",
"http://xyz/FrontDoor");
Works great. But I think there's a pattern or design that would elegantly allow me to encapsulate the "single-instance of each object contained in the dictionary" more.
For example, callers could do this:
DoorSensor door = null;
if (!server.ServerObjects.TryGetValue("DoorSensor",
"http://xyz/FrontDoor",
out door))
Debug.WriteLine("Something went very wrong");
I'm not really what to call this pattern. My ServerObjects are "single-instanced" by location. And my GetOrCreateServerObject is like a factory that lazy creates.
But it's possible for instances to be created that don't get put into the dictionary, which could lead to problems.
Like I said, what I have works... Cheers!
UPDATE 1/26/2011 10:13PM -
I just realized a potential problem: On the server side the object represented by a location/URL can actually be multi-inherited. It is THEORETICALLY possible for an object to be both a DoorSensor and an DigitalRelay.
I currently don't care about any of those cases (e.g. for garage doors I simplified my example above; there really is no DoorSensor I exposed, just a GarageDoorOpener which includes BOTH properties for sensing (e.g. Status) and actuation (e.g. Trigger). But this puts a wrinkle in my whole scheme if I were to care. Since this project is just for me :-) I am going to declare I don't care and document it.
I would propose the following simple idea:
PremiseObject's constructor is declared internal.
A special factory object is responsible for creating (or returning an already created) instances. The dictionary is a part of the factory.
Clients are located in another assembly.
This way PremiseObjects can be created by clients only through the factory. This way you can guarantee that only single instance of object exists for each location.
A variant of the idea would be to declare the PremiseObject's constructor private, and declare the factory a friend; but (unlike C++) C# doesn't have a friend notion.
Ok you can probably avoid a parameter and a cast (in the consumer code any way) with a generic method.
public abstract class PremiseObject
{
protected PremiseObject()
{
}
public string Location { get; set; }
public static void GetSensor<T>(string location, out T sensor)
where T : PremiseObject, new()
{
PremiseObject so;
if(_locationSingltons.TryGetValue(location, out so))
{
sensor = (T) so; // this will throw and exception if the
// wrong type has been created.
return;
}
sensor = new T();
sensor.Location = location;
_locationSingltons.Add(location, sensor);
}
private static Dictionary<string, PremiseObject> _locationSingltons
= new Dictionary<string, PremiseObject>();
}
Then the calling code looks a bit nicer:
DoorSensor frontDoor;
PremiseObject.GetSensor("http://FrontDoor/etc", out frontDoor);
So I like that calling convention - if you want to stay away from throwing an exception you can change the return type to bool and indicate failure that way. Personally I wouls say that an exception is what you want.
You may prefer the call without the out parameter - but if you do that then you have to supply the type to the method call - anyway defining the factory method would look like this:
public static T GetSensor<T>(string location) where T : PremiseObject, new()
{
PremiseObject so;
if (_locationSingltons.TryGetValue(location, out so))
{
return (T)so; // this will throw and exception if the
// wrong type has been created.
}
T result = new T();
result.Location = location;
_locationSingltons.Add(location, result);
return result;
}
Then the calling code looks like this:
var frontDoor2 = PremiseObject.GetSensor<DoorSensor>("http://FrontDoor/etc");
I like both these approaches because nothing has to be repeated. The type of the PremiseObject only gets stated once - there is no need for a string defining the type.
If you want to be really, really sure that no instances of PremiseObject get created that aren't placed in the dictionary, you could make the constructors all private, and create a static constructor (for each subclass) that took as a parameter the Dictionary object you're referring to. This static constructor would check the dictionary object to make sure that there wasn't an existing instance, and then return either the new or the existing instance as required. So something like this:
public class PremiseObject
{
public static Dictionary<string, PremiseObject> PremiseObjects { get; private set; }
static PremiseObject()
{
PremiseObjects = new Dictionary<string, PremiseObject>();
}
}
public class DerivedPremiseObject : PremiseObject
{
private DerivedPremiseObject()
{
}
public static DerivedPremiseObject GetDerivedPremiseObject(string location)
{
DerivedPremiseObject po = null;
if (!PremiseObject.PremiseObjects.TryGetValue(location, out po))
{
po = new DerivedPremiseObject();
PremiseObject.PremiseObjects.Add(location, po);
}
return po;
}
}
And there are a variety of similar strategies you could use. The key is to somehow make the constructor private and only allow access to the constructor through a static method that enforces the logic of the class construction.
Perhaps you could make PremiseObject a singleton, then you wouldn't have to worry about each object in the dictionary beign a single instance?
In the general case, setting access modifiers on your constructors should do the trick of not allowing anyone external to create the objects (barring reflection). However, these would need to be internal, so anything else in the assembly would be able to instantiate them.
I suspect many of your requirements may be met by using an off the shelf dependency injection container that supports singleton instances. It feels close, but maybe not quite the same. (possibly StrutureMap, Ninject, Castle Windsor, or Unity in no particular order)
Related
I have data from multiple organisations (police, fire, office) that need output in different formats.
To achieve this, I defined the following (this is a little simplified):
Transaction class -
"Success" indicator - Boolean.
"Type of department"- String or Enum.
A class which can be of any type - Police, Fire or Office (My question is on this as you will see).
A GenerateOutput() method - to handle generation of file formats.
Police class
Age - String
VehicleNumber - Integer
Supervisor - String
Fire class
Name - String
FireEngineNumber - Integer
County - Enum
WorkTimings - Enum
Office Class
Age - String
DeskNumber - Integer
Department - String
PayScale - Enum
IsManagement - Bool
As you can see, the Police, Fire and Office classes dont share anything in common and are primarily intended as data carrying entities. I intend to use a Factory to return an appropriate generic (not a C# generic) Transaction object with the data (Transaction object with Police, Fire or Office data within it) and then pass the returned object to a Strategy pattern which determines the file format (CSV, Excel, or XML; specified in a configuration file) each one needs.
My problem is in the definition of the Transaction object.
What type does the class in "3." of the Transaction class need to be? The data for each org differs, there are no common members, I am unable to define a common class for all.
Is the overall design appropriate? What other designs should I consider?
Based on Peter's comments below:
I think using generics might work, I ran into a problem though. I would like to use a factory to return the object requested, using GetTransactionObject, as below. What should be the return type of GetTransactionObject to accomodate this.
class TransactionFactory
{
Dictionary<string, Type> typeClassLookup;
public TransactionFactory()
{
typeClassLookup = new Dictionary<string, Type>();
typeClassLookup.Add("Police", typeof(PoliceData));
typeClassLookup.Add("Fire", typeof(FireData));
}
Transaction<????> GetTransactionObject(string org)
{
if( typeClassLookup.TryGetValue(org, out typeValue))
{
switch (typeValue.ToString())
{
case "policeData":
transactionObject = new Transaction<PoliceData>() { Data = new PoliceData(), params = null};
case "FireData":
transactionObject = new Transaction<FireData>() {Data = new FireData(), params = null};
}
}
return transactionObject;
If the types really have nothing in common, then you need no explicit base class. System.Object suffices, just as with many other generic types (i.e. any generic type lacking a constraint).
In other words, you could declare as:
class Transaction<T>
{
public bool Success { get; private set; }
public T Entity { get; private set; }
public Transaction(bool success, T entity)
{
Success = success;
Entity = entity;
}
public void GenerateOutput() { /* something goes here */ }
}
Personally, I would avoid adding a "department type" member. After all, that's implicit from the type parameter T. But you could add that easily to the above if you want.
If and when you find that the types do have something in common, such that your Transaction<T> type needs to do more than simply hold onto an instance of one of those types (which is about all it can do without a constraint), then you will be able to put that commonality into an interface or base class (depending on the specific need), and specify that in a constraint for the Transaction<T> class.
Note that it's not clear what you mean for the GenerateOutput() to do, or how it should work. But assuming that you want output that is specific for each Entity value, it seems to me that that is your "something in common". I.e., it's not the Transaction<T> class at all that needs to implement that method, but rather each entity type. In that case, you have something like this:
interface IDepartmentEntity
{
void GenerateOutput();
}
class Office : IDepartmentEntity
{
public void GenerateOutput() { /* department-specific logic here */ }
}
// etc.
Then you can declare:
class Transaction<T> where T : IDepartmentEntity
{
public bool Success { get; private set; }
public T Entity { get; private set; }
public Transaction(bool success, T entity)
{
Success = success;
Entity = entity;
}
public void GenerateOutput() { Entity.GenerateOutput(); }
}
EDIT:
Per Prasant's follow-up edit, with a request for advice on the GetTransactionObject()…
The right way to do this depends on the caller and the context, a detail not provided in the question. IMHO, the best scenario is where the caller is aware of the type. This allows the full power of generics to be used.
For example:
class TransactionFactory
{
public Transaction<T> GetTransactionObject<T>()
where T : IDepartmentEntity, new()
{
return new Transaction<T>()
{
Data = new T(),
params = null
}
}
}
Then you call like this:
Transaction<FireData> transaction = factory.GetTransactionObject<FireData>();
The caller, of course already knowing the type it is creating, then can fill in the appropriate properties of the transaction.Data object.
If that approach is not possible, then you will need for Transaction<T> itself to have a base class, or implement an interface. Note that in my original example, the IDepartmentEntity interface has only one method, and it's the same as the GenerateOutput() method in the Transaction class.
So maybe, that interface is really about generating output instead of being a data entity. Call it, instead of IDepartmentEntity, something like IOutputGenerator.
In that case, you might have something like this:
class Transaction<T> : IOutputGenerator
{
// all as before
}
class TransactionFactory
{
public IOutputGenerator GetTransactionObject(string org)
{
if( typeClassLookup.TryGetValue(org, out typeValue))
{
switch (typeValue.ToString())
{
case "policeData":
transactionObject = new Transaction<PoliceData>() { Data = new PoliceData(), params = null};
case "FireData":
transactionObject = new Transaction<FireData>() {Data = new FireData(), params = null};
}
}
return transactionObject;
}
}
This is an inferior solution, as it means the caller can only directly access the IOutputGenerator functionality. Anything else requires doing some type-checking and special-case code, something that really ought to be avoided whenever possible.
Note: if the Transaction type has other members which, like the GenerateOutput() method, are independent of the contained type T here, and which would be useful to callers who don't know T, then a possible variation of the above is to not reuse the interface used for the department-specific data types, but instead declare a base class for Transaction<T>, named of course Transaction, containing all those members not related to T. Then the return value can be Transaction.
What type does the class in "3." of the Transaction class need to be?
To decouple your department classes from the various export types, I recommend you make the department classes implement a common interface. Something like this:
public interface Exportable {
// return a list of attribute names, values, and types to export
IList<Tuple<String, String, Type>> GetAttributes();
}
For example:
public class Police : Exportable {
public IList<Tuple<String, String, Type>> GetAttributes() {
// return list size 3 - attribute info for Age, VehicleNumber, Supervisor
}
}
Is the overall design appropriate? What other designs should I consider?
The Transaction class design doesn't seem well suited for this problem.
Consider an Export class with a method for each export type, each method which receives the attributes returned from the Exportable interface method. Basic outline:
public static class Export {
public static boolean CSV(IList<Tuple<String, String, Type>> attributes) {
// export attributes to CSV, return whether succeeded
}
public static boolean Excel(IList<Tuple<String, String, Type>> attributes) {
// export attributes to Excel, return whether succeeded
}
// same thing for XML
}
Suppose I have following object:
object[] objs = new object[3]{ "this is sample string", 42L, 1};
and I want to do something to the individual objects in the array like
foreach (object o in objs)
{
/// logic here
mylogic();
}
Now mylogic() will only take object parameters so there is boxing going on, but we require to be able to do something based on the type of the object, so we would do something like :
public void dosomething(object obj)
{
// one way
if(obj.GetType() == typeof(string))
{
// string specific something
}
// another way
if(obj is long)
{
// long specific something
}
}
Well it's ugly and non performance, is there a better way possible using generics or any other way?
Your values are already boxed, because they are stored in an object[]. So no additional boxing takes place when you pass them to a method taking an object argument.
The object[] is where I would aim my focus - is it really necessary to represent your data like that? Do you really not know their structure? It would be preferable to define a class (or a structure) to hold your data, and also to contain the methods that act on the data - then you know a type of each field or property at design and compile time, and you can use this information in further code. In your case that might look like:
class Container
{
public string StringProperty { get; set; }
public long LongProperty { get; set; }
public int IntProperty { get; set; }
public void DoSomething()
{
// string specific something with StringProperty
// long specific something with LongProperty
// int specific something with IntProperty
}
}
That way you begin to encapsulate your data and make sure it is located close to the logic that uses them. Even better might be to make the properties into private readonly fields, so they are not even visible to the outside.
You could try looking into using the dynamic keyword in C# 4.0 and later and see if that helps you. It would be better to define your own class and make properties of the different types and just use those instead.
The memory overhead would be minimal and you'd avoid all the boxing penalties.
IMO, in such cases one should ask the question: is there anything wrong with the code design? What is the idea of the array containing different types of objects? What do they represent? May be you need a separate class that holds these different objects...
As strange as it might sound, I want to access something that is not.
Here's an example:
int tempVar = myObject.myVar // myVar does not exist;
In reality I want the class to run a method, that would take the non-existing variable as a parameter:
object returningVariables(string variableName)
{
object desiredObject; // a concrete object that I have stored somewhere in an array inside the class
// going trough some List that contains names of all variables, when it finds it
// return it
return desiredObject;
}
I'll try to explain in a concrete example what I want to achieve and why.
I have a class that stores stats of an object: name, level, speed, size, etc.
They are supposed to be accessed trough a method StatData getStat(string statName);
Stats are created trough a method void MakeStat(). The problem began when some stats were created in the class as public variables and accessed by other classed not trough the getStat() method.
Now that the public variables are changed, deleted or new ones added it takes some refactoring to get the app working again. And it looks bad when there are mixed calls with direct access to a public variable and a method for the same thing.
Please note, I do know how to fix my code the standard way; I am merely interested if above described technique will work.
Sounds like DynamicObject would help you here. You can override different methods for of that class for whatever is being called/accessed on that object: members, invocations, etc. Using dynamic means you won't be able to use intellisense anymore however. You can find more info here.
public class MyDynamicObject : DynamicObject {
public override bool TryGetMember(GetMemberBinder binder, out Object result){
if (binder.Name == "myVar"){
result = "xyz";
return true;
}
result = null;
return false;
}
}
// Usage
dynamic x = new MyDynamicObject();
Console.WriteLine (x.myVar); // will output "xyz"
Rephrased the question. Scroll down for the original
Ok, maybe I should have given you the whole picture. I have many classes which look like this:
public class Movement : Component
{
private Vector3 linearVelocity;
public Vector3 LinearVelocity
{
get
{
return linearVelocity;
}
set
{
if (value != linearVelocity)
{
linearVelocity = value;
ComponentChangedEvent<Movement>.Invoke(this, "LinearVelocity");
}
}
}
// other properties (e.g. AngularVelocity), which are declared exactly
// the same way as above
}
There are also classes called Transform, Mesh, Collider, Appearance, etc. all derived from Component and all have nothing but properties which are declared as described above. What is important here is to invoke the ComponentChangedEvent. Everything works perfectly, but I was looking for a way where I don't have to rewrite the same logic for each property again and again.
I had a look here and liked the idea of using generic properties. What I came up with looks like this:
public class ComponentProperty<TValue, TOwner>
{
private TValue _value;
public TValue Value
{
get
{
return _value;
}
set
{
if (!EqualityComparer<TValue>.Default.Equals(_value, value))
{
_value = value;
ComponentChangedEvent<TOwner>.Invoke(
/*get instance of the class which declares value (e.g. Movement instance)*/,
/*get name of property where value comes from (e.g. "LinearVelocity") */);
}
}
}
public static implicit operator TValue(ComponentProperty<TValue, TOwner> value)
{
return value.Value;
}
public static implicit operator ComponentProperty<TValue, TOwner>(TValue value)
{
return new ComponentProperty<TValue, TOwner> { Value = value };
}
}
Then I would use it like this:
public class Movement : Component
{
public ComponentProperty<Vector3, Movement> LinearVelocity { get; set; }
public ComponentProperty<Vector3, Movement> AngularVelocity { get; set; }
}
But I am not able to get the instance where LinearVelocity comes from nor it's name as string. So my question was, if all of this is possible...
But it seems that I have no option other than keep doing it the way I was, writing this logic for each property manually.
Original Question:
Get instance of declaring class from property
I have a class with a property:
public class Foo
{
public int Bar { get; set; }
}
In another context I have something like this:
Foo fooInstance = new Foo();
DoSomething(fooInstance.Bar);
Then, in DoSomething I need to get fooInstance from having nothing but parameter. From the context, it is save to assume that not any integers are passed into DoSomething, but only public properties of ints.
public void DoSomething(int parameter)
{
// need to use fooInstance here as well,
// and no, it is not possible to just pass it in as another parameter
}
Is that possible at all? Using reflection, or maybe a custom attribute on the property Bar?
Why do you want to send just a property to DoSomething, send it the whole object :), so it would become,
DoSomething(fooInstance);
Your function will then accept object instead of parameter. You can use an overload of this function to make sure that old code doesn't break.
There are several ways to deal with implementing INotifyPropertyChanged. You're doing almost the same thing, except you don't implement the interface and raise the event in a different way. But all of the solutions apply for you too.
Like you do, call a method with a string parameter: OnPropertyChanged("Property").
Call a method with a lambda that uses the property: OnPropertyChanged(() => Property). The advantage of this is that it's compile-time checked for typos and refactoring-friendly.
Use caller information to inject the name of the property: OnPropertyChanged(). This will work in C# 5.
Use something like Castle DynamicProxy to create a derived class at runtime that will call the method for you. This means you need to make your properties virtual and that you need to create instances of the class only through Castle.
Use an AOP framework to modify the code of your properties after compilation to call the method.
there's no way to get fooInstance from parameter. parameter is passed by value, and is only a copy of the value of fooInstance.Bar, it no longer has anything to do with fooInstance
That being said, the obvious solution is to write DoSomething like this
public void DoSomething(Foo parameter)
{
// need to use fooInstance here as well,
// and no, it is not possible to just pass it in as another parameter
}
Property is just a field, which returns reference to some object on heap (i.e. its address). If property is not of reference type, it returns value of object.
So, when you do something like
DoSomething(fooInstance.Bar);
You just passing address of object Bar to method.
If Bar is reference type (i.e. class). Imagine that Mr.Foo has an address of Mr.Bar (462 for Marion County, Indiana). Mrs.CLR asks Mr.Foo for address of Mr.Bar. And then tells this address to somebody who needs address of Mr.Bar. How somebody will know, that CLR asked Foo about address of Bar? He received only an address 462 for Marion County, Indiana.
In case of value objects (int, double, structs etc), Mr.Foo has a cool mp3 track named Bar. Mrs. CLR creates a copy of that mp3 track and sends it to somebody. How somebody will know, that his mp3 track Bar is a copy of Mr.Foo's track?
So, if you want somebody to know about Mr.Foo, you need to pass an address of Mr.Foo to him:
DoSomething(fooInstance);
With this address somebody can visit Mr.Foo and ask him about address of Mr.Bar, or create a copy of his mp3 track :)
In .net how do I fetch object's name in the declaring type. For example...
public static void Main()
{
Information dataInformation = new Information();
}
public class Inforamtion
{
//Constructor
public Inforamtion()
{
//Can I fetch name of object i.e. "dataInformation" declared in Main function
//I want to set the object's Name property = dataInformation here, because it is the name used in declaring that object.
}
public string Name = {get; set;}
}
As far as the CLR goes, there's not really a way to determine an object's name. That sort of information is stored (to some extent) in the debugging information and the assembly, but it's not used at runtime. Regardless, the object you're referring to is just a bunch of bytes in memory. It could have multiple references to it with multiple names, so even if you could get the names of all the variables referencing the object, it would be impossible to programmatically determine which one you're looking to use.
Long story short: you can't do that.
That is the variable name, not the object name. It also poses the question: what is the name here:
Information foo, bar;
foo = bar = new Information();
You can't do this for constructors etc; in limited scenarios it is possible to get a variable name via Expression, if you really want:
public static void Main()
{
Information dataInformation = new Information();
Write(() => dataInformation);
}
static void Write<T>(Expression<Func<T>> expression)
{
MemberExpression me = expression.Body as MemberExpression;
if (me == null) throw new NotSupportedException();
Console.WriteLine(me.Member.Name);
}
Note that this relies on the capture implementation, etc - and is generally cheeky.
I don't think this is possible.
But at the first place, why do you need something like this??
With my experience i have realized that if you need something weird from a compiler or a language which is not offered, then (most often) it means that there is something wrong with the approach or the logic.
Please reconsider why are you trying to achieve this.