Reputation: 3472
Updated
What is the best way to setup this class? i.e. call the SetupInstruction()
method? I want to make this method virtual so a class that overrides can have its own implementation. In the overridden class I will set up other objects/properties.
public abstract class InstructionInfo : IInstruction
{
protected readonly IUserSession UserSession;
protected readonly IReadOnlySession ReadOnlySession;
protected InstructionInfo(int instructionID)
{
InstructionID = instructionID;
}
protected virtual void SetupInstruction()
{
_myInstruction = null; //call db and set up...
}
#region interface members
private Instruction _myInstruction;
public Instruction MyInstruction
{
get
{
**SetupInstruction();**
return _myInstruction;
}
private set { _myInstruction = value; }
}
#endregion
}
Upvotes: 0
Views: 125
Reputation: 113222
For the most part, I'd just design a class to set-up those fields it needs itself in its own constructor, and let derived classes set up those that are just for them in theirs.
If I wanted the way a particular field was set to be overridden, then I'd make all use of it happen through a lazy-loaded property.
public abstract class MyClass
{
private SomeType _someField = null; // Never touch this field in any member but
// the SomeProp property
// Maybe use Lazy<SomeType> to make this more obvious.
protected SomeType CreateSomeType();
public SomeType SomeProp
{
get
{
return _someField = _someField ?? CreateSomeType();
}
}
}
Now I don't think about "setting up" the object, I just act as if it always has SomeProp
ready to go, and as long as I don't use it in the constructor, it'll work.
If that wouldn't work in a particular case, I'd consider the factory pattern or the repository pattern.
Upvotes: 0
Reputation: 2203
Your InstructionInfo is an entity. The setup method should be moved to a repository class eg. InstructionInfoRepository.GetInstructionInfoByID() for example.
You can later inject the upcasted InstructionInfoRepository (e.g. IInstructionInfoRepository) into other components to decouple the database access & Instruction instantiation logic. You can also inject a mock IInstructionInfoRepository into those same components during unit testing to avoid external resource dependencies during unit testing. During integration testing, you can then test your concrete implementation of the IInstructionInfoRepository.
Upvotes: 0
Reputation: 62248
May be I missed something, but just a sample:
// a Base abstract class
public abstract class MyAbs
{
public MyAbs() {
Init();
}
public virtual void Init(){
"Do base".Dump();
}
}
//derived
public class Derived : MyAbs
{
public override void Init(){
"Do child".Dump();
}
}
code to run, a sample
Derived ab = new Derived();
Output? Based on OO principles is :
"Do child"
Hope this what you want.
Upvotes: 0
Reputation: 8613
It all depends how you intend on using the code. If you want the setup process to be internal, then you may want to call that method from within the constructor of the base type. Setup can then be customized by derived types through overriding the method. Similarly, if you want to run some common setup tasks with a step where custom setup can occur, you could create a setup similar to this:
protected InstructionInfo(...)
{
// ...
SetupInstruction();
}
private void SetupInstruction()
{
// Common setup
// ...
// Custom setup
SetupInstructionCore();
}
// Either an optionally overriddable method
protected virtual void SetupInstructionCore()
{
}
// Or a required override
protected abstract void SetupInstructionCore();
Upvotes: 1
Reputation: 20764
I think I dont fully understand your question, but you should make the setter of MyInstruction
protected
, so the overriding class can set it in SetupInstruction()
.
You also should give the property a better name eg Instruction
instead of MyInstruction
.
Upvotes: 0