I have the following method in public abstract A : IVirtualMachineExporter :
public override void Prepare() { ... }
I call the Prepare from another class B:
public sealed class B
{
public new ExportJobRequest Request { get { return (ExportJobRequest)base.Request; } }
private void ExportTask()
{
IVirtualMachineExporter exporter = CreateExporter();
exporter.Prepare();
}
}
Request containing public bool isAdHoc { get; set; }. I want to use information from this property inside Prepare(). How can I do this? I don't want to change Prepare() signature.
How can I do this without changing Prepare signature?
Well, somehow Prepare needs an instance to call isAdHoc on, so if you don't want to change the method signature, can you change the class or interface?
something like:
IVirtualMachineExporter exporter = CreateExporter(Request);
exporter.Prepare();
or
IVirtualMachineExporter exporter = CreateExporter();
exporter.Request = Request;
exporter.Prepare();
In class A, expose a public property IsAdhoc.
Set the IsAdhoc property on class A, prior to calling Prepare from class B.
So...
Class A
public bool IsAdhoc { get; set; }
// Inside this method, do something based on the IsAdhoc property above.
public override void Prepare() { ... }
Class B
public sealed class B
{
public new ExportJobRequest Request { get { return (ExportJobRequest)base.Request; } }
private void ExportTask()
{
IVirtualMachineExporter exporter = CreateExporter();
exporter.IsAdhoc = this.Request.isAdhoc;
exporter.Prepare();
}
}
Or, you could pass the boolean value to the CreateExporter method, which could set it on the new exporter class via its constructor.
It looks like B depends on an IVirtualMachineExporter, and the implementation of IVirtualMachineExporter (A) depends on a Request.
B shouldn't know anything about A or what it depends on. It should only care about the IVirtualMachineExporter interface and calling Prepare().
You could create it like this:
public abstract class A : IVirtualMachineExporter
{
private readonly ExportJobRequest _request;
public A(ExportJobRequest request)
{
_request = request;
}
public override void Prepare()
{
//Now Prepare() has access to the Request because
//it's contained within A, the class that actually needs it.
}
}
Similarly, pass an interface (not a concrete implementation) to the constructor for B.
public sealed class B
{
private readonly IVirtualMachineExporter _exporter;
public B(IVirtualMachineExporter exporter)
{
_exporter = exporter;
}
private void ExportTask()
{
//Can this isAdhoc property be a property of IVirtualMachineExporter,
//or can the Request be a property? Will every implementation of the
//interface have a request?
//exporter.IsAdhoc = this.Request.isAdhoc;
_exporter.Prepare();
}
}
I don't have the specifics of your design. But if B is going to depend on an interface (IVirtualMachineExplorer) then it shouldn't know or care about any of the inner details of any class that implements the interface.
Related
Think my understanding about OO is wrong.
Say I have these classes
public class BaseValidator{
public Result Validate(BaseRequest r){
xxxx
}
}
public class BaseRequest{
}
Then in my child class, I have this:
Public class ChildValidator : BaseValidator{
public Result Validate(ChildRequest r){
xxxx,
base.Validate(r);
}
}
public class ChildRequest: BaseRequest{
}
When using the classes:
BaseValidator cr = new ChildValidator();
ChildRequest r = new ChildRequest();
cr.Validate(r);
I thought this will call ChildValidator's Validate method, but turned out it calls BaseValidator's method.
What is the right way to do this? I want to pass my ChildValidator to another method, which takes BaseValidator as a parameter.
You are currently casting ChildValidator to BaseValidator, as such you are calling BaseValidator.Validate(BaseRequest) which at present has a different signature to ChildValidator.Validate(ChildRequest). You can pass an instance of ChildRequest to either method without issue because it inherits from BaseRequest.
Without this cast you would call ChildValidator.Validate() as you are expecting:
ChildValidator cr = new ChildValidator();
ChildRequest r = new ChildRequest();
cr.Validate(r); // Calls ChildValidator.Validate() method
If you want the ChildValidator.Validate() method to always be called then you would need to use a virtual / override method. You can't do that as your classes are currently written because you are accepting different parameter types (BaseRequest and ChildRequest).
Interfaces
You could utilise interfaces to help you out in this case, as shown below:
public interface IValidator {
bool Validate(IRequest r);
}
public class BaseValidator : IValidator {
public virtual bool Validate(IRequest r) {
return true;
}
}
public class ChildValidator : BaseValidator {
public override bool Validate(IRequest r) {
return base.Validate(r);
}
}
public interface IRequest { }
public class ChildRequest : BaseRequest { }
public class BaseRequest : IRequest { }
With the above classes / interfaces the original calls would work as follows:
BaseValidator cr = new ChildValidator(); // cast to BaseValidator
ChildRequest r = new ChildRequest();
cr.Validate(r); // Still calls ChildValidator.Validate() method
Generic Class
Alternatively, and as Jon Skeet pointed towards, you may want to look at implementing a generic Validator class. That could perhaps look something like the below:
public class Validator<T> where T : BaseRequest {
public bool Validate(T r) {
return true;
}
}
public class BaseRequest { }
public class ChildRequest : BaseRequest { }
You can use that as below:
var validator = new Validator<ChildRequest>();
ChildRequest request = new ChildRequest();
validator.Validate(r);
The best method for you will depend on the rest of your implementation and what the methods are doing.
I'm trying to use DI to bind a different implementation of my networking class. I've been able to do this successfully using a none generic version of the class. My implementation is as follows:
class MainClass
{
public static void Main(string[] args)
{
IKernel kernel;
// Hardcode here but will be managed by build system.
bool runningInProd = false;
if (runningInProd)
{
kernel = new StandardKernel(new RealNetworkModule());
}
else
{
kernel = new StandardKernel(new FakeNetworkModule());
}
Session session = kernel.Get<Session>();
session.Authenticate();
}
public class RealNetworkModule : NinjectModule
{
public override void Load()
{
Bind(typeof(IRequestSender)).To(typeof(RealRequestSender));
}
}
public class FakeNetworkModule : NinjectModule
{
public override void Load()
{
Bind(typeof(IRequestSender)).To(typeof(FakeRequestSender));
}
}
}
Class that uses my IRequestSender:
public class Session
{
IRequestSender requestSender;
[Inject]
public Session(IRequestSender requestSender)
{
this.requestSender = requestSender;
}
public void Authenticate()
{
Console.WriteLine(requestSender.Send("Hello There"));
}
}
The IRequestSender interface:
public interface IRequestSender
{
string Send(string request);
}
And the two different implementations:
public class RealRequestSender: IRequestSender
{
public string Send(string request)
{
return "RealRequestSender right back at you: " + request;
}
}
public class FakeRequestSender: IRequestSender
{
public string Send(string request)
{
return "FakeRequestSender right back at you: " + request;
}
}
This is very straightforward and it works; however, what I need is for my IRequestSender to use Generic types rather than string for input output:
public interface IRequestSender<RequestT, ResponseT> where RequestT: class where ResponseT: class
{
RequestT Send(RequestT request);
}
And the impl's:
public class FakeRequestSender<RequestT, ResponseT> : IRequestSender<RequestT, ResponseT> where RequestT : class where ResponseT : class
{
public RequestT Send(RequestT request)
{
throw new NotImplementedException();
}
}
public class RealRequestSender<RequestT, ResponseT> : IRequestSender<RequestT, ResponseT> where RequestT : class where ResponseT : class
{
public RequestT Send(RequestT request)
{
throw new NotImplementedException();
}
}
I've come across several examples that address this issue and I've tried to base my implementation on them but I have failed. Here are the two problems that I'm running into:
1) Binding: this is the main problem. Here is what my binding looks like based on solutions I have seen online:
public class RealNetworkModule : NinjectModule
{
public override void Load()
{
Bind(typeof(IRequestSender<>)).To(typeof(RealRequestSender<>));
}
}
VSCode gives me the error:
Program.cs(29,29): Error CS0305: Using the generic type 'IRequestSender<RequestT, ResponseT>' requires 2 type arguments (CS0305) (DI)
Based on this error and what I have read online it is still not clear to me what I need to do here.
2) Accessing IRequestSender: the solution to this might be clear once I know how to fix binding. In the original implementation I used [Inject] to get access to the IRequestSender I need in my Sessions class. However now in the generic version I imagine I will not be able to do this. If I were to use RequestSender without DI it would look like:
RequestSender <AuthRequest, AuthResponse> requestSender = new RequestSender<AuthRequest, AuthResponse>();
or
RequestSender <UserRequest, UserResponse> requestSender = new RequestSender< UserRequest, UserResponse >();
for any number of different types.
So I'm not sure how to go about accessing the RequestSender in this scenario.
Given your current interface, you'll have to specify the generic type arguments when injecting. Assuming your request and response are both strings, your constructor would look like:
public Session(IRequestSender<string, string> requestSender)
{
this.requestSender = requestSender;
}
If you don't want to specify the arguments at creation/injection time, you'll have to change the design a bit. I can't say for certain with the sample code you provided, but it might be possible to remove the generic type args from your interface and place them on the method instead:
public interface IRequestSender
{
RequestT Send<RequestT, ResponseT>(RequestT request)
where RequestT: class
where ResponseT: class;
}
With that definition, you'd inject IRequestSender, and then specify the generic type parameters when calling. For example,
string myResponse = requestSender.Send<string, string>("my string");
I have this class hierarchy:
public abstract class AClass : SomeFrameworkClass {
[WorkOnThisProperty(With.Some.Context)]
private MyObject MyProperty { get; set; }
public override void OnSomethingHappened() {
ExternalFramework.WorkOn(this);
}
}
public class BClass : AClass {
// ... Snip ...
}
ExternalFramework is operating on this: an instance of BClass but i need it to operate on this as an instance of AClass because ExternalFramework only works on the type of the object passed in and does not go up the inheritance hierarchy. How can i downcast this into AClass so ExternalFramework can actually detect MyProperty?
I've tried casting this to object and then to AClass, and casting it directly to AClass but as the cast is unnecessary it doesn't seem to run. What can i do about this?
EDIT: ExternalFramework is Cheeseknife. I am trying to inject a couple views into a base fragment class that has all the reusable logic while child fragment classes implement some specific behaviour tuning.
The problem is that all private members of a class can only be accessed inside of the same class.
With this code:
class A { private string Property { get; set; } }
class B : A { public string Proxy => Property; }
We'll get compilation error because class B cannot access private property from class A, but if change keyword to protected :
class A { protected string Property { get; set; } }
It should work.
I have a child class Bicycle that inherits from Agent. The agent has a property which depends on the bicycle to define it. Namely, the physics model for the agent needs to be initialised with the velocity and acceleration constraints which are defined on a per-bicycle-basis and would be different for another type of agent.
The problem I have is that I cannot pass the parameters I need to calculate (the velocity/acceleration require calculations to draw them from a theoretical distribution) for this in the base() constructor because of course the child class hasn't yet been instantiated.
The calculations are done once per bicycle instance but are used multiple times so a simple static method won't do the job. I can just call a protected method in the parent after they're calculated but AFAIK there's no way to enforce this in the child, or more particularly in any future children which I might not write.
So for example, I could:
public abstract class Agent
{
protected IPhysics PluginPhysics { get; set; }
protected Agent(...)
{
}
}
public class Bicycle : Agent
{
private double maxA;
public Bicycle(Object anotherParameter) : base(...)
{
maxA = ComputationOfMaxA();
this.PluginPhysics = new Physics(anotherParameter, maxA);
}
private static double ComputationOfMaxA()
{
...
}
...
}
or I could:
public abstract class Agent
{
protected IPhysics PluginPhysics { get; private set; }
protected Agent(...)
{
}
protected void SetupPhysics(Physics physics)
{
this.PluginPhysics = physics;
}
}
public class Bicycle : Agent
{
private double maxA;
public Bicycle(Object anotherParameter) : base(...)
{
maxA = ComputationOfMaxA();
SetupPhysics(new Physics(anotherParameter,maxA));
}
private static double ComputationOfMaxA()
{
...
}
...
}
I'd rather not do either of those as there's no compile-time way to ensure that the child initialises PluginPhysics that I can think of, and I'd rather PluginPhysics not be able to be changed once it's been initialised. I'd also rather not have the parts of the parameters that need to go into Physicsoutside the Bicycle class. I appreciate that all these things might not be simultaneously possible.
So short of strongly worded documentation or a bunch of run-time null checks in the parent class before any of the relevant class objects are called on, is there an obvious C#-ish way I'm missing of forcing a child to initialise a parent class field before use if you can't do it in the constructor?
d4Rk's answer was very close, however you should try not call virtual methods from a constructor as bad things can happen. However if you use a combination of Lazy loading tricks and ISupportInitialize you can defer the creation of the plugin till after the constructor is finished.
public abstract class Agent : ISupportInitialize
{
private bool _initialized = false;
private IPhysics _pluginPhysics;
protected IPhysics PluginPhysics
{
get
{
if(!_initialized)
EndInit();
return _pluginPhysics;
}
}
protected Agent(...)
{
}
protected abstract IPhysics CreatePhysics();
ISupportInitialize.BeginInit()
{
//We make this a explicit implementation because it will not
//do anything so we don't need to expose it.
}
public void EndInit()
{
if(_initialized)
return;
_initialized = true;
_pluginPhysics = CreatePhysics();
}
}
public class Bicycle : Agent
{
private double maxA;
Object _anotherParameter;
public Bicycle(Object anotherParameter)
{
_anotherParameter = anotherParameter;
}
protected override IPhysics CreatePhysics()
{
ComputationOfMaxA();
return new Physics(anotherParameter, maxA);
}
}
The user of your class will need to call EndInit() after they get a object back to cause the IPhysics object to be created, however if they forget to call the initialize function the getter on the physics object will trigger the initialize call itself the first time it is used.
You could do everything I have shown without the ISupportInitialize interface and just having a public Initalize() method on the base class but I like to expose framework interfaces when they fit.
What about enforcing the subclass to implement a CreatePhysics method, and call this in the base ctor?
Like this:
public abstract class Agent
{
protected IPhysics PluginPhysics { get; private set; }
protected Agent(...)
{
var physics = CreatePhysics();
SetupPhysics(physics);
}
void SetupPhysics(IPhysics physics)
{
this.PluginPhysics = physics;
}
protected abstract IPhysics CreatePhysics();
}
public class Bicycle : Agent
{
private double maxA;
protected override IPhysics CreatePhysics()
{
ComputationOfMaxA();
return new Physics(maxA);
}
}
How about making the constructor for Agent take the IPhysics object and making it protected Then in your Bicycle class, you are forced to call the constructor on the base which sets up your class property:
public class Agent
{
protected IPhysics PluginPhysics { get; private set; }
protected Agent(IPhysics physicsPlugin)
{
PluginPhysics = physicsPlugin;
}
}
public class Bicycle : Agent
{
public Bicycle(IPhysics physicsPlugin)
: base(physicsPlugin)
{
Console.WriteLine("Bicycle ctor");
}
}
I have a base class which has a nested type, inside. There's a function in the outer (base) type which would be overridden by it's children later. In fact this function belongs to the inner type from the OO prespective but still I need it, to be overridden by subtypes of the base class.
Should I use this function as a callback from the inner type or just move it inside the inner type and let's the subtypes to override it from there?
EDIT: Sample code added
class A
{
protected void func() { /* do something */ }
class B { /**/ }
}
// OR
class A
{
class B
{
protected void func() { /* do something */ }
}
}
// Then
class C : A
{
override func() { /**/ }
}
My suggestion is to crate a delegate for the inner type function which is initiated by the constructor of the base class:
internal class BaseClass
{
public BaseClass(Action myAction)
{
this.innerType = new InnerType(myAction);
}
public BaseClass()
{
// When no function delegate is supplied, InnerType should default to
// using its own implementation of the specific function
this.innerType = new InnerType();
}
}
As you see, deriving types can call the base constructor with :base (overridenAction) where they can provide their own implementation of the function right to the innermost type. Of course, you are not obligated to use Action but any delegate you want.
IMO what you are describing looks like The Strategy design pattern. Consider using this pattern. Your code would be much more maintainable as it contains well recognizable pattern. You also can take a look at state design pattern, usually you have to choose between these two, they are closely connected.
In this scenario:
class A
{
class B
{
protected void func() { // do something }
}
}
You cannot derive from class A and override func() in class B.
From your description it seems that A-derived classes should be able to override some function (or functionality) in the inner class B which indicates that you maybe should rethink your design. Either extract B and don't make it an inner class or make the functionality you want to override an explicit dependency via an interface like this:
class A
{
private B _MyB;
public A(ISomeBehaviour behaviour)
{
_MyB = new B(behaviour);
}
}
In anyway if you want to stick with your design then I would not recommend the delegate approach and rather choose the override because with the delegates it makes it harder to add decoration if that is all you need in your child classes.
This is how the outer class can serve as a strategy to the inner service class.
Note that using pattern names such as TemplateMethod and Strategy as real class names is not recommended, use whatever is meaningful in the domain. Same applies to Outer and Inner.
public class Consumer
{
public void Foo()
{
IOuterFoo fooService = new Derived();
fooService.OuterFoo();
}
}
// ...
public interface IOuterFoo
{
void OuterFoo();
}
abstract class Base : Base.IStrategy, IOuterFoo
{
public void OuterFoo() { _service.Foo(); }
private readonly InnerService _service;
protected Base() { _service = new InnerService(this); }
private interface IStrategy { void Foo(); }
private class InnerService
{
private readonly IStrategy _strategy;
public InnerService(IStrategy strategy) { _strategy = strategy; }
public void Foo() { _strategy.Foo(); }
}
void IStrategy.Foo() { TemplateMethodFoo(); }
protected abstract void TemplateMethodFoo();
}
class Derived : Base
{
protected override void TemplateMethodFoo()
{
throw new NotImplementedException();
}
}