I have an app that supports two data access layers: db4o and RavenDB. The logic classes make calls like this to get a concrete data class:
return DataAccessFactory.GetDataInterface<IApplicationData>().GetAll();
Here is the method in DataAccessFactory that returns the correct ApplicationData (db4o or RavenDB) concrete class:
public static T GetDataInterface<T>() where T : class
{
T theObject = // Code here to get the object. Not relevant to this question.
// Begin HACK
DataAccessLayerBase theObjectAsRavenDalBase = theObject as DataAccessLayerBase;
if (theObjectAsRavenDalBase != null)
{
theObjectAsRavenDalBase.SetAsInitialDalInstanceAndCreateSession();
}
// End HACK
return theObject as T;
}
The hack that I've implemented is casting to RavenDB's version of DataAccessLayerBase and that if statement. If the concrete class happens to be a RavenDB class, then I need to call a method on it. (The DataAccessLayerBase, shown here, is in the RavenDb namespace. db4o also his its own DataAccessLayerBase.)
One way to fix this would be to have each DataAccessLayerBase implement a common method, like Initialize(). The db4o Initialize() method would do nothing, and the RavenDB Initialize() method would perform the necessary logic. Then this method could simply call Initialize() and not care which concrete class it was.
Is there a better design than this? I think the fix that I just described is decent enough, but I can't help but think I'm missing something. I'm looking for a better, more elegant way to solve this. One drawback with my proposed approach is that other data access layers must then implement Initialize() even though I only needed it for RavenDB.
Note: I can't just have the concrete classes do this initialization when they're created, because it should only happen when a call is made to DataAccessFactory.GetDataInterface<>().
One other solution would be to add a type property on an interface implemented by your DataAccess classes. You could then check the type to know if you need to call the SetAsInitialDalInstanceAndCreateSession method. I think the Initialize method you describe above is a good solution too though
Related
I need to unit test a method that returns a type I can't easily fake or instantiate. The type implements IQueryable<T> which I originally thought I could use to my advantage, but I don't see how at this point.
For example:
public sealed class MyTrickyClass<T> : IQueryable<T>
{
...
}
public MyTrickyClass<T> GetData()
{
return repository.GetAllData();
}
and my unit test
[Test Method]
public void CanGetData()
{
var data = (new List<Record>() { new Record() }).AsQueryable();
var mockRepository = new Mock<IRepository<Record>>();
mockRepository.Setup(s => s.GetAllData()).Returns(data);
MyService service = new MyService(mockRepository.Object);
var result = service.GetData();
Assert.IsNotNull(result);
}
This won't compile because the return type of GetAllData() is MyTrickyClass<T>. If I try to cast data to a MyTrickyClass<Record> type, the cast fails.
All this makes sense, but it leaves me wondering what the right solution is. What are some workarounds for this kind of situation? I may be able to change the MyTrickyClass, but ideally I'd like to find a solution that leaves it alone.
You could have MyTrickyClass<T> implement interface ITrickyClass<T>, which inherits from IQueryable<T>. That seems minimally invasive to your class itself, and you'd have a good seam for mocking.
Your data variable in the test is an IQueryable<Record>, not a MyTrickyClass<Record>.
Here are some possibilities for fixing it:
Change data in the test to be a MyTrickyClass<Record> (though I'm guessing if this was possible you'd already have done it)
Make MyTrickyClass easier to construct, then do the above
Change the interface of IRepository so that it returns an IQueryable instead of a MyTrickyClass (which is best if all it needs is the IQueryable anyway)
Wrap the repository in a layer which lets you also wrap the return value. It's another layer of abstraction, but if you find you can't change the repository or MyTrickyClass then you probably want to be isolating yourself from it anyway
As #Erik Dietrich suggested, you could make MyTrickyClass implement an interface. However, you still won't be able to create data using an IQueryable as the cast will fail. You could create a mock of ITrickyClass instead, though, or create a little stub class that implements the interface (if MyTrickyClass is a domain object, you'll probably be using it in a lot of places anyway, so a hand-coded stub may be more useful).
I've got a class that I would like to inherit. i.e. ExpenseForm should inherit from Spreadsheet. Spreadsheet is provided by a third party: I can't change it.
But parent class instances are usually generated with a static method:
Spreadsheet myExpenses = Spreadsheet.Open(filename);
(And Spreadsheet implements iDisposable, so the above statement is actually at the top of a using section, but I don't think that really affects this.)
I'd like to have
ExpenseForm myExpenses = ExpenseForm.Open(filename);
This fails, of course, since ExpenseForm.Open (inherited from Spreadsheet) returns a Spreadsheet object.
What's the best way to solve this? Maybe extension methods? (I have no experience with those.)
I've gone a different direction; ExpenseForm now has an instance of Spreadsheet. (This feels a little messier, since I have to keep track of my disposable object to clean up when I'm done.) But it seems like I'm missing a way to solve the original inheritance problem.
Well you can create your own ExpenseForm.Open method easily enough:
public static new ExpenseForm Open(string file)
{
// Do whatever you need
}
That's assuming you can create a subclass, i.e. that there are appropriate constructors you can chain to. You say that you would normally use Spreadsheet.Open, but are there protected or public constructors available?
Personally I'd favour the composition route anyway - do you actually want other code to treat an ExpenseForm as if it were any other kind of Spreadsheet? I'm generally more of a fan of composition than inheritance - it makes code easier to reason about, in my experience.
If Spreadsheet objects can only be created by means of a static function, then inheritance is not an option. Just provide your own Open static function within ExpenseForm that returns an object of that kind.
I know interfaces cannot define constructors. Here's what I wish I could do:
public interface SavableObject {
void Save(ObjectSaver saver);
SavableObject(ObjectLoader loader); //This, obviously, doesn't work
}
//Loading an object inside ObjectLoader:
T LoadObject<T>() where T : SavableObject {
return (T)Activator.CreateInstance(typeof(T), this);
}
And I could do this if I took out the line that didn't work, and there would just be a runtime error when trying to load (or possibly save, if I put an assert in there) the object if it didn't have the constructor. I'm just wondering if there's any way to require a class to have a particular constructor that can be used with the Activator. Can I use a custom attribute somehow, and require that attribute to be on the class? Or must I rely on runtime checks to load and save data?
I know I could have a parameterless constructor and a Load(ObjectLoader) method but I don't necessarily want to have a parameterless constructor available to abuse for other purposes.
what about ISerializable?
In brief I suggest you use generics as most factories do.
public interface SavableObject<T> : where T : new
{
void Save(IObjectSaver<T> saver);
SavableObject<T> Load(ObjectLoader loader); //This, obviously, doesn't work
}
However, you seem to have turned it on it head. The class is doing what factory must do. So I do not think it is such a good idea to pass the factory to the entity itself and that is part of the problem you are experiencing in the design.
If you are not afraid of using Reflection, like Activator that you have shown, you can do little trick I tend to use:
Make parameterless constructor that is protected
Make Load method, that is also protected (or private, I tend to use virtual protected so I support inheritance)
Create new object using this non-public constructor (through reflection - you can't create instance of your class "just like that" using new operator)
Invoke load method (also using reflection - no one will call it later).
I don't know if this will work for you, but I used that method when I needed to deserialize pretty big game state and it was pretty fast, eventhough all this reflection (for many reasons I did not wanted to use built-in serialization methods and Factory Pattern wouldn't do, so I tend to treat this method as something that may be useful if other methods fail, on the other hand, if I could - I would probably use built-in serialization for simplicity).
How about adding a property on your interface:
public interface SavableObject
{
void Save(ObjectSaver saver);
ObjectLoader ObjectLoader {get; set;}
}
Then in your factory:
T LoadObject<T>() where T : SavableObject
{
var result = (T)Activator.CreateInstance(typeof(T));
result.ObjectLoader = this;
return result;
}
Based on your question and comments.
I think you should do it at runtime using reflection.
Combining constructors and interfaces is ilogical from its core. Interface is about what concrete instance can do, not how to initialize it. This can only be achived using abstract class.
Maybe using factory to create instance of the class?
Also I don't think you can get better speed than default ISerializable implementation. Unless you are .NET GURU and have years of time for it.
Short answer: It's not possible, I guess. There are no attributes or generalizations I can use to require a specific kind of constructor on a class.
I have a base class (order) with a set of sub classes (productorder, specialorder, partsorder etc).
Only Some of these sub classes implement a particular interface (ITrackingCustomer) which has a single method declaration (object getcustdetails()).
As part of my solution all of my orders are processed in a central place, i.e. any crud methods pass through a central layer. Within this central layer I want to do the following:
If order is of type ITrackingCustomer
Then invoke method getcustdetails()
I have this working using the following code:
if (typeof(ITrackingCustomer).IsAssignableFrom(Order.GetType()))
{
MethodInfo theMethod = Order.GetType().GetMethod("getcustdetails");
object y = theMethod.Invoke(Order, null);
}
I am happy with the first part using isassignablefrom but would like to use a less performance intensive method for the second part (i.e. the reflection using invoke).
My question is:
Is there a more efficient way of doing this as I have read that using the invoke command is costly.
ITrackingCustomer ord = Order as ITrackingCustomer;
if (ord != null)
{
object y = ord.getcustdetails();
}
You can do:
if(Order is ITrackingCustomer) {
((ITrackingCustomer)Order).getcustdetails();
}
As others have mentioned, you can use the is and as operators to determine if an object is of a certain type. However, polymorphism is usually better suited for solving this type of problem.
If it is feasible, perhaps you can place a getcustdetails() method on Order. Make it virtual if it has a suitable default implementation (i.e. return no details or null), or abstract if it makes sense that all Order types must implement it. Since you have the ITrackingCustomer interface, I suspect that an abstract method won't work well. However, for Order types that implement ITrackingCustomer, you can then implement getcustdetails() accordingly.
At this point, it sounds like you would be able to do away with ITrackingCustomer, but I can't say for certain without knowing more details about how this interface is used.
Once this is done, you won't need to perform any type checks since calling Order.getcustdetails() always dispatches to the correct concrete implementation.
If you are trying to do call by name instead of invoking a member in an interface and you want to be able to call the same method thousands of times, then other than a cast (which I assume you can't do because you don't know the type) or reflection is to JIT compile the call.
Rick Strahl has a nice blog article on the performance costs of various ways to call method and the comments lead to this article which shows how to pull a delegate out to a non-virtual method.
Finally, I wrote a blog article on how to build adapter classes on the fly. What you can do with that is make a directly callable object that meets an abstract class:
public abstract class CustomerDetailsGetter {
public abstract object getcustdetails();
}
// ...
AdapterCompiler compiler = new AdapterCompiler();
AdapterFactory<CusomterDetailsGetter> factory = compiler.DefineAdapter<CustomerDetailsGetter>(Order.GetType());
// now, my code assumes you want to construct an object from whole cloth
// but the code could be changed to invoke the default constructor and set the
// adapted object.
CustomerDetailsGetter getter = factory.Construct(null)
object info = getter.getcustdetails();
Now, I need to be clear - there are only two reasons to do this:
you want to be able to have call-by-name semantics when you know the target arguments at compile time and you don't know have the target assembly, and you want your code to be CLEAN. An example of this is code that knows it wants to create and use a particular object, but doesn't know if the assembly will be available until run time and is forbidden to have a reference.
you want to call object methods a la reflection, but want to do this fast, fast, fast and will be calling them thousands or millions of times.
If it's a "call once" thing, you're way better off writing a helper method to do what you want.
Greetings,
I have a particular object which can be constructed from a file, as such:
public class ConfigObj
{
public ConfigObj(string loadPath)
{
//load object using .Net's supplied Serialization library
//resulting in a ConfigObj object
ConfigObj deserializedObj = VoodooLoadFunction(loadpath);
//the line below won't compile
this = thisIsMyObj;
}
}
I want to, in essense, say "ok, and now this object we've just deserialized, this is the object that we in fact are." There are a few ways of doing this, and I'm wondering which is considered a best-practice. My ideas are:
Build a copy-into-me function which copies the object field by field. This is the current implementation and I'm pretty sure its a horrible idea since whenever a new member is added to the object I need to also remember to add it to the 'copy-into-me' function, and there's no way that's maintainable.
Build a static method for the ConfigObj class which acts as a de-facto constructor for loading the object. This sounds much better but not very best-practice-y.
I'm not entirely happy with either of the two, though. What is the acknowledged best practice here?
Your second option is what is called a factory method and is a common design technique. If you do use this technique, you may find that you need to know the type of class you will load before you actually load the class. If you run into this situation, you can use a higher level type of factory that looks at the stream and calls the factory method for the appropriate type of class.
There's nothing wrong with having a static method instead of a constructor. In fact, it has a number of advantages.
I always go with the static method. Usually it's kind of a hierarchy which is loaded, and therefore only the root object needs the method. And it's not really an unusual approach in the .NET framework (e.g. Graphics.FromImage), so it should be fine with users of your class.