Observable objects / dynamic interfaces? - c#

I'm currently looking for a nice and clean way to manage/store application configuration. I've seen many approaches and frameworks, yet I'm not really satisfied because most I've seen follow a simple idea:
* Store 'some' data
* Retrieve 'some' data
Which might look like this (pseudo) for a simple key value store:
public T Get<T>(string key);
public void Save<T>(string key, T value);
The .NET configuration framework living inside System.Configuration that has been around for a while tackles this nicely because it allows strongly typed configuration objects by providing a set of base classes which one can derives from to describe the configuration scheme. However this requires a lot of work and boilerplate code to get things running.
What I got in mind is something like this:
public IConfiguration<TSet> : TSet {
void Commit();
void Refresh();
}
public class MyConfigurationSet {
public string Value1 { get; set; }
public int Value2 { get; set; }
}
// usage
var config = new JsonConfiguration<MyConfigurationSet>(MYPATH);
config.Value1 = "Hello";
config.Commit();
Is there any way to make such a thing possible? In order to do this, I would need to a) derive from a generic type and b) "observe" an instance of that generic type for changes in order to track changes etc., and I'm not aware of a way those things are possible (for now, e.g. for the first part, I can't see any reason why it isn't possible other than it's currently not). Anyone got an idea?

Deriving from a generic type is no problem:
public class JsonConfiguration<T> : IConfiguration<T>
{
}
Is perfectly permissible.
As far as observing it goes, I would put a generic type constraint on the type implementing INotifyPropertyChanged so that you can register for the PropertyChanged event. You can't just "trap" a random variable assignment, the client code has to notify you.
public class JsonConfiguration<T> : IConfiguration<T> where T:INotifyPropertyChanged
{
}

Related

Design Pattern to use for customizable/extendable classes with constructors

Starting with the use case.
Let's consider the base for this questions is a big framework and implementations of business objects of some software.
This software hast to be customized quite regularly, so it would be preferred that most of the C# objects are extendable and logic can be overriden. Even "model data".
The goal would be to be able to write code, create objects with input parameters - that may create more objects etc - and you don't have to think about whether those objects have derived implementations in any way. The derived classes will be used automatically.
For ease of uses a typesafe way to create the objects would be preferred as well.
A quick example:
public class OrderModel
{
public int Id { get; set; }
public string Status { get; set; }
}
public class CustomOrderModel : OrderModel
{
public string AdditionalData { get; set; }
}
public class StockFinder
{
public Article Article { get; }
public StockFinder(Article article)
{
Article = article;
}
public virtual double GetInternalStock() { /*...*/ }
public virtual double GetFreeStock() { /*...*/ }
}
public class CustomStockFinder : StockFinder
{
public bool UsePremiumAvailability { get; }
public CustomStockFinder(Article article, bool usePremiumAvailability)
: base(article)
{
UsePremiumAvailability = usePremiumAvailability;
}
protected CustomStockFinder(Article article) : this(article, false) { } // For compatibility (?)
public override double GetFreeStock() { /*...*/ }
}
In both cases I wanna do stuff like this
var resp = Factory.Create<OrderModel>(); // Creates a CustomOrderModel internally
// Generic
var finderGeneric = Factory.Create<StockFinder>(someArticle);
// Typesafe?
var finderTypesafe1 = Factory.StockFinder.Create(someArticle); // GetFreeStock() uses the new implementation
var finderTypesafe2 = Factory.StockFinder.Create(someArticle, true); // Returns the custom class already
Automatically generating and compiling C# code on build is not a big issue and could be done.
Usage of Reflection to call constructors is okay, if need be.
It's less about how complicating some code generation logic, written code analyzers, internal factories, builders etc are, and more about how "easy" and understandable the framework solution will be on a daily basis, to write classes and create those objects.
I thought about tagging the relevant classes with Attributes and then generating a typesafe factory class automatically on build step. Not so sure about naming conflicts, or references that might be needed to compile, as the constructor parameters could be anything.
Also, custom classes could have different constructors, so they should be compatible at each place in default code where they might be constructed already, but still create the custom object. In the custom code then you should be able to use the full custom constructor.
I am currently considering several different cases and possibilities, and can't seem to find a good solution. Maybe I am missing some kind of design pattern, or am not able to look outside of my bubble.
What would be the best design pattern or coding be to implement use cases like this?

Creating a Generic Save() Method for Models

I have a fairly simple system, and for the purposes of this question there are essentially three parts: Models, Repositories, Application Code.
At the core are the models. Let's use a simple contrived example:
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
In that same project is a generic repository interface. At its simplest:
public interface IRepository<T>
{
T Save(T model);
}
Implementations of that interface are in a separate project and injected with StructureMap. For simplicity:
public class PersonRepository : IRepository<Person>
{
public Person Save(Person model)
{
throw new NotImplementedException("I got to the save method!");
// In the repository methods I would interact with the database, or
// potentially with some other service for data persistence. For
// now I'm just using LINQ to SQL to a single database, but in the
// future there will be more databases, external services, etc. all
// abstracted behind here.
}
}
So, in application code, if I wanted to save a model I would do this:
var rep = IoCFactory.Current.Container.GetInstance<IRepository<Person>>();
myPerson = rep.Save(myPerson);
Simple enough, but it feels like it could be automated a lot. That pattern holds throughout the application code, so what I'm looking to do is create a single generic Save() on all models which would just be a shorthand call to the above application code. That way one would need only call:
myPerson.Save();
But I can't seem to figure out a way to do it. Maybe it's deceptively simple and I'm just not looking at it from the correct angle. At first I tried creating an empty ISaveableModel<T> interface and intended to have each "save-able" model implement it, then for the single generic Save() method I would have an extension on the interface:
public static void Save<T>(this ISaveableModel<T> model)
{
var rep = IoCFactory.Current.Container.GetInstance<IRepository<T>>();
model = rep.Save(model);
}
But it tells me that rep.Save(model) has invalid arguments. It seems that it's not wiring up the type inference as I'd hoped it would. I tried a similar approach with a BaseModel<T> class from which models would inherit:
public class BaseModel<T>
{
public void Save()
{
this = IoCFactory.Current.Container.GetInstance<IRepository<T>>().Save(this);
}
}
But the compiler error is the same. Is there a way to achieve what I'm trying to achieve? I'm very flexible on the design, so if I'm going about something all wrong on an architectural level then I have room to step back and change the big picture.
Would a generic extension method solve it?
public static T Save<T>(this T current)
{
var rep = IoCFactory.Current.Container.GetInstance<IRepository<T>>();
rep.Save(current);
}
You can then constrain it to your ISaveableModel<T> interface. Return type above not implemented, but you can put it to a boolean or status flag, whatever.
In both approaches, the parameter to the Save() function is not of type T. In the first one, it is ISaveableModel<T>, and in the second, it is BaseModel<T>. Since the repository is a generic based on T, Save method will expect a variable of type T. You can add a simple cast to T before you call Save to fix it.
Alternatively, your IRepostory<T> can be changed to
public interface IRepository<T>
{
T Save(ISaveableModel<T> model);
}
which makes more sense.

Limiting access to a public setter to specific objects (C#)

I'm trying to create a class (in C#) that serves as an environment for my application.
I'm trying to make the class dynamic, and send it as a parameter to entities in my application. The problem is, that I want to be able to change the properties of this environment class (public setters), but at the same time I want the classes that receive the environment to be unable to use these setters.
I can't seem to find a good way to phrase my question (which I figure is a part of the reason I can't find anything like this on Google or msdn), but to put shortly, I want to create a class with setters that are public only for some of my objects and not for all.
I'm currently amusing the following idea:
Avoiding the public setters all together, and expose the private fields using event registration.
The class will register to events in a new third object (sent as a parameter to the constructor). The methods that will be registered by the environment are not much more then setters, and so triggering these events will "allow access" to the private fields.
I'd love some ideas (seeing as I feel that mine isn't all that great), or better yet some patterns I could make use of.
Thanks in advance
Isn't "internal" sufficient for what you need?
And you could move the setters into an interface as explicit implementation. Then they are hidden from the public interface and only accessible if you cast to the interface.
And if you want to make really sure that nobody else can call it you can add some parameter to these functions where you expect a certain token object which you only give to trusted classes.
void SetX(int value, object token)
{
if(token!=correctToken)
throw new ArgumentException("wrong token");
x=value;
}
You could create a proxy, and send that proxy to your entity classes.
class MyClass
{
public int MyProperty { get; set; }
}
class MyProxyClass
{
public MyProxyClass(MyClass myClass)
{
_myClass = myClass;
}
private MyClass _myClass;
public int MyProperty
{
get { return _myClass.MyProperty; }
}
}
You could try using Friend assemblies. That will allow only the assemblies you specify to have access to your privates (snicker).
Maybe i understood something not quite well, but i think Jon had a quite similar problem which he described here. Maybe this can help you.
How about
class Callee
{
public void SetX(TypeOfCaller caller, int value)
{
}
}
class TypeOfCaller
{
public void Do()
{
Callee instance;
//..
instance.SetX(this, 5);
}
}
Doing so; you can also use Visual Studio' Find References feature! In case you want multiple types of caller; you can either opt for class hierarchy or can simply have required overloads
Why not return clones of your protected objects instead of the actual objects? Solves the problem without adding any more complexity.
public class MyService
{
private List<MyObject> _protectedObjects = new List<MyObject>();
public MyObject GetItem(int id)
{
return (MyObject)_protectedObjects.First(i => i.Id == id).Clone();
}
}
public class MyObject : ICloneable
{
//[...]
public object Clone()
{
return MemberwiseClone();
}
}

How to make 2 incompatible types, but with the same members, interchangeable?

Yesterday 2 of the guys on our team came to me with an uncommon problem. We are using a third-party component in one of our winforms applications. All the code has already been written against it. They then wanted to incorporate another third-party component, by the same vender, into our application. To their delight they found that the second component had the exact same public members as the first. But to their dismay, the 2 components have completely separate inheritance hierarchies, and implement no common interfaces. Makes you wonder... Well, makes me wonder.
An example of the problem:
Incompatible Types http://www.freeimagehosting.net/uploads/f9f6b862f1.png
public class ThirdPartyClass1
{
public string Name
{
get
{
return "ThirdPartyClass1";
}
}
public void DoThirdPartyStuff ()
{
Console.WriteLine ("ThirdPartyClass1 is doing its thing.");
}
}
public class ThirdPartyClass2
{
public string Name
{
get
{
return "ThirdPartyClass2";
}
}
public void DoThirdPartyStuff ()
{
Console.WriteLine ("ThirdPartyClass2 is doing its thing.");
}
}
Gladly they felt copying and pasting the code they wrote for the first component was not the correct answer. So they were thinking of assigning the component instant into an object reference and then modifying the code to do conditional casts after checking what type it was. But that is arguably even uglier than the copy and paste approach.
So they then asked me if I can write some reflection code to access the properties and call the methods off the two different object types since we know what they are, and they are exactly the same. But my first thought was that there goes the elegance. I figure there has to be a better, graceful solution to this problem.
My first question was, are the 2 third-party component classes sealed? They were not. At least we have that.
So, since they are not sealed, the problem is solvable in the following way:
Extract a common interface out of the coinciding members of the 2 third-party classes. I called it Icommon.
public interface ICommon
{
string Name
{
get;
}
void DoThirdPartyStuff ();
}
Then create 2 new classes; DerivedClass1 and DerivedClass2 that inherit from ThirdPartyClass1 and ThirdPartyClass2 respectively. These 2 new classes both implement the ICommon interface, but are otherwise completely empty.
public class DerivedClass1
: ThirdPartyClass1, ICommon
{
}
public class DerivedClass2
: ThirdPartyClass2, ICommon
{
}
Now, even though the derived classes are empty, the interface is satisfied by the base classes, which is where we extracted the interface from in the first place.
The resulting class diagram looks like this.
alt text http://www.freeimagehosting.net/uploads/988cadf318.png
So now, instead of what we previously had:
ThirdPartyClass1 c1 = new ThirdPartyClass1 ();
c1. DoThirdPartyStuff ();
We can now do:
ICommon common = new DerivedClass1 ();
common. DoThirdPartyStuff ();
And the same can be done with DerivedClass2.
The result is that all our existing code that referenced an instance of ThirdPartyClass1 can be left as is, by just swapping out the ThirdPartyClass1 reference for a ICommon reference. The ICommon reference could then be given an instance of DerivedClass1 or DerivedClass2, which of course in turn inherits from ThirdPartyClass1 and ThirdPartyClass2 respectively. And all just works.
I do not know if there is a specific name for this, but to me it looks like a variant of the adaptor pattern.
Perhaps we could have solve the problem with the dynamic types in C# 4.0, but that would have not had the benefit of compile-time checking.
I would be very interested to know if anybody else has another elegant way of solving this problem.
If you're using .Net 4 you can avoid having to do alot of this as the dynamic type can help with what you want. However if using .Net 2+ there is another (different way) of achieving this:
You can use a duck typing library like the one from Deft Flux to treat your third party classes as if they implemented an interface.
For example:
public interface ICommonInterface
{
string Name { get; }
void DoThirdPartyStuff();
}
//...in your code:
ThirdPartyClass1 classWeWishHadInterface = new ThirdPartyClass1()
ICommonInterface classWrappedAsInterface = DuckTyping.Cast<ICommonInterface>(classWeWishHadInterface);
classWrappedAsInterface.DoThirdPartyStuff();
This avoids having to build derived wrapper classes manually for all those classes - and will work as long as the class has the same members as the interface
What about some wrappers?
public class ThirdPartyClass1 {
public string Name {
get {
return "ThirdPartyClass1";
}
}
public void DoThirdPartyStuff() {
Console.WriteLine("ThirdPartyClass1 is doing its thing.");
}
}
public interface IThirdPartyClassWrapper {
public string Name { get; }
public void DoThirdPartyStuff();
}
public class ThirdPartyClassWrapper1 : IThirdPartyClassWrapper {
ThirdPartyClass1 _thirdParty;
public string Name {
get { return _thirdParty.Name; }
}
public void DoThirdPartyStuff() {
_thirdParty.DoThirdPartyStuff();
}
}
...and the same for ThirdPartyClass2, then you use the wrapper interface in all your methods.
Add an interface. You could add one wrapper (that implements the interface) for each of the 3rd parties.
Anyway, if you have the code of those 3rd parties, you could skip the wrapper thing and directly implement the interface. I'm quite sure you don't have the source, though.

How can I implement an interface that can take many object types

excuse what seems like a real noobie question but how can I implement the following
public interface IViewModel {
void Map<T>();
}
public class CarViewModel : IViewModel
{
public string Color { get; private set; }
public int Tyres { get; private set; }
public CarViewModel(Car _car)
}
//this is where the problem is - there can be many differnt kind of object but I want them all to implement a Map function. I want to be able to assign the properties to incoming object. I also need to cater for IList of cars coming in that need to be populated. I suspect I am not using Generics properly
public void Map<T>(Car _car){
Color = _car.Color;
Tyres = _car.Tyres;
}
Do you mean this?
public interface IViewModel<T>
{
void Map(T domainObject);
}
public class CarViewModel : IViewModel<Car>
{
public Map(Car domainObject) { ... }
}
You say:
I suspect I am not using Generics properly
and you are correct. Additionally, you are not using polymorphism properly.
If you want to polymorphically accept several different types that all have something in common, then you need to create an interface that is the parent type of all of the types you will be using. You can do this without using any Generics at all.
What Generics (aka parametric polymorphism) gives you is a way to create one type that is parameterized by another type (and thus behaves like many different types). For example, IList<T> is parameterized by a type variable T -- then IList<string> and IList<int> are two separate types (with many possible subtypes each), but you only have to write the code once.
What are your actual requirements for this design? What are your ViewModel classes trying to accomplish?

Categories

Resources