I have a class and it has a method:
public class A{
public virtual void doChanges (String message, object[] args){
}
}
Some classes use 'doChange' method in 'A':
public class MethodClaller{
A a = new A();
public void caller(){
a.doChanges ("Test",null);
}
}
And ALL child classes should override doChanges:
public class B:A{
public override void doChanges(String message, object[] args){
}
}
Problem is: I want to use Class A and Class MethodCaller in several programs(like component) and in each program, method doChange should automatically call for all childs of A, whenever doChange called for A. so a code like this:
new MethodCaller.call();
should call doChanges in all instances of B.
It sounds like event handling. But I don't know how to do it. It doesn't matter if A and B are not relative as parent and child in solution. I just had feeling that this is the correct structure.
You are using inheritance where a pattern is in order.
Instead of B inheriting from A (which is just a static dependency between the two classes) you should register the instances of B so that an instance of A can delegate. Look up the delegation pattern to understand this sentence.
Doing this is the first conceptual step, but later on you will probably (nobody can say it for sure) end up with something larger, which is the Composite Pattern.
To have the instances automatically registered in the composite, you'll use the creational Factory Pattern.
It will go like this:
A will allow its instances to be composites;
B will be a component that may be attached to A;
you will fave a factory method on B to instantiate elements of B which requires an instance of A:
A a; // get the instance "a" from somewhere
B.Create(a); // will create an instance of B and attach it to a
To force this usage you'll privateize the constructor of B as the usual (see factory pattern).
The Create() will be something like this:
private B() // prevent direct instance creation
{
// ...
}
public static void Create(A a)
{
B b;
b = new B();
a.Register(b);
}
So you're sure ALL B are atached to an A (analog of your requirement all B must extend A).
The Register() in A will be:
private List<B> _bs = new List<B>();
public void Register(B b)
{
_bs.Add(b);
}
The Do() in A will be:
public void Do(object args)
{
// pre-procedure of A
foreach (B b in _bs)
{
b.Do(args);
}
// post-procedure of A
}
Now to be sure that B implements the Do() method without using the static dependency between classes leverage the composite pattern by defining a component interface:
interface AComponent
{
void Do(object args);
}
Derive B from it:
class B implements AComponent
{
...
And finally refer the interface (instead of B) from A:
private List<AComponent> _components = new List<AComponent>();
public void Register(AComponent component)
{
_components.Add(component);
}
public void Do(object args)
{
// pre-procedure of A
foreach (AComponent component in _components)
{
component.Do(args);
}
// post-procedure of A
}
The last step is decouple B from A in the create method by using a composite interface:
interface AComposite
{
void Register(AComponent component);
}
Derive A from it:
class A implements AComposite
{
...
Use the interface in the create method:
public static void Create(AComposite composite)
{
composite.Register(new B());
}
Now you have A and B loosely coupled but instances of B must be registered on instances of A so that when Do() fires, all instances of B also fire their Do() methods.
As a benefit you can have implementations of AComponent that are completely different from B (as per inheritance) and still have them fire their Do() methods, to. You can even mix-up instances of different implementations of AComponent, just like polymorphism allows through virtual methods.
Does this make any sense to you?
Related
So, here is my code. The output is 2255. But I caanot understand why method in class A will be executed, for we haven't signed the event on it, as we haven't created an instance of class A.
using System;
public delegate void EvHappened();
class A{
protected int a = 0;
public event EvHappened AEv;
public A() {
this.AEv += EvAHappenedHandler;
}
public void EvAHappenedHandler(){
if (a > 3)
this.a++;
Console.Write(a);
}
public void methodA() {
this.AEv();
}
}
class B : A{
public event EvHappened BEv;
public void EvBHappenedHandler() {
this.a += 2; methodA(); Console.Write(a);
}
public void method(){
this.BEv();
}
}
class Program{
static void Main(string[] args){
B b = new B();
b.BEv += b.EvBHappenedHandler;
for (int i = 0; i < 2; i++){
b.method();
}
}
}
As you haven't declared any constructors in B, the compiler has provided a default constructor - it's as if you'd written:
public class B {
public B() : base() {
}
// Rest of class here
}
So when you call new B(), the A constructor will be executed. That constructor subscribes to the AEv event.
If you had declared a constructor yourself, the behaviour would depend on the constructor initializer:
With a constructor initializer of the form this(...), the constructor would chain to another constructor in the same class. Eventually this "chain" will end up with a call to a constructor in the base class.
With a constructor initializer of the form base(...), the constructor would chain to the specified constructor in the base class.
If you don't specify a constructor initializer at all, it's equivalent to one of the form base().
So whatever you do in the derived class, any constructor always ends up going through a constructor in the base class.
This is pure OOP:
When you create object B which inherits class A. The Constructor for A will be called.
Example:
class A
{
public A()
{
Console.WriteLine("Constructor Of A");
}
}
class B : A
{
public B()
{
Console.WriteLine("Constructor Of B");
}
public void method()
{
}
}
Usage:
B b = new B();
Output:
Constructor Of A
Constructor Of B
If you really need to Create class B without running the Constructor:
B b = (B)FormatterServices.GetUninitializedObject(typeof(B));
Note: You should not use this unless you know what you are doing, as per MSDN.
Because the new instance of the object is initialized to zero and no
constructors are run, the object might not represent a state that is
regarded as valid by that object. The current method should only be
used for deserialization when the user intends to immediately populate
all fields. It does not create an uninitialized string, since creating
an empty instance of an immutable type serves no purpose.
Yes. Class A's constructor is called when you instantiate Class B
B b = new B();
which in turn, registers the handler. The design of Class A is basically saying that derived classes have no right to change the inherited behaviour. If you want the opposite at least make EvAHappenedHandler virtual.
I have Unity injection implemented on constructors. I have the follow:
interface IA
{
DoSomething();
}
class A : IA
{
private List<MyType> List;
public A(List<MyType> list)
{
this.List = list;
}
DoSomething()
{
// do something with this.List
}
}
interface IB
{
List<MyType> GetList();
}
class B : IB
{
public List<MyType> GetList() { }
}
class C
{
private A MyA;
public C(IB b)
{
this.MyA = new A(b.GetList());
}
public DoSomethingInA()
{
this.MyA.DoSomething();
}
}
I want to remove the "new A()" in constructor of class C and use injection of IA but I dont know how to register A of type IA receiving in constructor a property of an instance and not an instance itself.
I can't change implementation of A !! a List<> should be received in constructor.
Thanks in advance !
The constructor of class C does too much; injector constructors should be simple. So instead of calling GetList during construction of the object graph, postpone this till a later moment and just inject IB in both A and C as follows:
class A : IA
{
private IB b;
public A(IB b) {
this.b = b;
}
DoSomething() {
var list = this.b.GetList();
// do something with this.List
}
}
class C
{
private IB b;
public C(IB b) {
this.b = b;
}
}
This simplifies your registration, your code, and allows you compose object graphs with confidence.
UPDATE
In case the type is out of your control, you should consider it 3rd party type. In general, you should be careful in letting such type be auto-wired by the container, since the people that maintain that type might add new constructors to that type, which might break your DI registration (more info here).
So instead of letting the container auto-wire that type, register a lambda expression that creates the instance of that 3rd party type. For instance:
container.Register<IA>(new InjectionFactory(c => new A(c.Resolve<IB>().GetList())));
Do note however, that in this case you're still doing too much during the building of the object graph, and (depending on what GetList does under the covers) that might make it harder to verify the correctness of the graph.
So because you are working with a 3rd party type that depends on some runtime types during its construction, you might want to consider postponing the creation of that type. If you create a proxy class for IA, you will be able to delay the creation of A without the application to know anything about it. That proxy might look something like this:
class DelayedAProxy : IA
{
private readonly Lazy<IA> a;
public DelayedAProxy(Lazy<IA> a) {
this.a = a;
}
public DoSomething() {
this.a.Value.DoSomething();
}
}
And you can register it as follows:
container.Register<IA>(new InjectionFactory(c =>
{
var lazy = new Lazy<IA>(() => new A(c.Resolve<IB>().GetList()));
new DelayedAProxy(lazy);
}));
Here we don't register A directly, but DelayedAProxy instead and that proxy will only cause A to be created when DoSomething is executed for the first time, which will be after the complete object graph is created.
Alternatively, your proxy could also just depend on IB and create the lazy internally. That would like this:
class DelayedAProxy : IA
{
private readonly Lazy<IA> a;
public DelayedAProxy(IB b) {
this.a = new Lazy<IA>(() => new A(b.GetList()));
}
public DoSomething() {
this.a.Value.DoSomething();
}
}
Advantage of this is that the registration of the DelayedAProxy becomes much easier:
container.RegisterType<IA, DelayedAProxy>();
Although it looks like in this case the DelayedAProxy constructor is doing again a lot, in fact it just creates the Lazy with the delegate. GetList is only called after the construction of the proxy.
I ended up changing the design and injecting dependency using a method and not a constructor, something like:
interface IA
{
Initialize(List<something> list);
DoSomething();
}
class C
{
private IA MyA;
public C(IB b, IA a)
{
this.MyA = a;
this.MyA.Initialize(b.GetList());
}
public DoSomethingInA()
{
this.MyA.DoSomething();
}
}
Initialization is done in constructor to less impact the current code calling DoSomething(), could be also possible something that:
public DoSomethingInA()
{
this.MyA.DoSomething(b.GetList());
}
but as I said, it impacts much more the existing code.
I know it sounds trivial, but is it somehow possible to return the b field when i pass an A variable to a function which expects an IMyIntercace? Then i don't have to implement the Hello() function in the class A, instead i just return b as the IMyInterface.
interface IMyInterface
{
void Hello();
}
class A : IMyInterface
{
B b = new B();
}
class B : IMyInterface
{
public void Hello()
{
Console.WriteLine("Hello");
}
}
class Program
{
static void foo(IMyInterface myInterface)
{
myInterface.Hello();
}
static void Main(string[] args)
{
A someVariable = new A();
foo(someVariable);
}
}
I suppose it cant be done, but is there any design pattern or trick that could do it?
EDIT
The reason i dont want to derive A is because maybe i want to do this
class A : IMyInterface
{
B b = new B();
B b2 = new B();
IMyInterface bPointer;
}
Then i can point to one of the b's depending on some situation
You could inherit A from B.
A will continue to implement the interface and you may override every function you need to change in the future.
interface IMyInterface
{
void Hello();
}
class A : B
{
}
class B : IMyInterface
{
public void Hello()
{
Console.WriteLine("Hello");
}
}
No. Either A implements IMyInterface, in which case you don't need to do anything, or it does not, in which case there is no way to automatically "redirect" any interested parties to the b member.
You can either expose b (and preferably make it a property) to the outside world so that they can refer to it as required, or you can make A implement IMyInterface and manually forward all calls to b like this:
class A : IMyInterface
{
B b = new B();
public void Hello()
{
b.Hello();
}
}
Just make A.b public (or internal) and then call foo(someVariable.b).
What you want to have is interface delegation and unfortunately there is nothing built into the language to help you with that.
Basically, the A class has to implement the interface.
One way it can do that is of course to derive from B:
class A : B
{
}
But if you don't want to do that, then you need to delegate. What you have to do is to implement the delegation yourself so that you can delegate the responsibility of the actual implementation to the B class, you won't get any help from the compiler to fix this.
class A : IMyInterface
{
B b = new B();
public void Hello()
{
b.Hello();
}
}
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();
}
}
The base class user should access the original method
class A
public init()
The derived class user should aceess ONLY the derived method.
class B
public init(int info)
I cannot use "override" bc there's a different signature.
What options do I have so that the derived class user does not see two methods.
Notes.
All in all I just need two classes that share some code. Inheritance is not a must.
But simplicity for the user of B is a priority.
This is a big code smell (and violates some basic OOP tenets) and, to the best of my knowledge, can not be done in any language. In OOP, an instance of B is an instance of A; this is polymorphism. So if A has a public method named init accepting no parameters, then so does B.
What are you trying to do this for?
Edit: Now that you've added the edit that states that inheritance is not a must, just use composition to share code. Give B a private instance of A, for example.
According to the Liskov principle you simply cannot do that, because it would violate this principle. The best thing you can to is override init() in the derived class and make it throw an exception every time it's invoked, stating that the user should use init(int info) and rely on the test to catch the errors.
Why you can't simple replace the init() method or even make it protected?
The Liskov principle states (rephrased) that where an instance of class A is required, an isntance of class B extends A can be passed.
If a method expects A and wants to call init() on it and you pass B (which extends A) to it with a protected init() the method will fail. This is the reason why the code will not even compile.
What you're asking for is impossible, due to the nature of the type system. Any instance of B can be thought of as an A, so you can call any of A's methods (including Init()). The best you can do is overload Init() in B and throw an exception to catch this at runtime.
public class B
{
void Init()
{
throw new NotSupportedException();
}
}
Contrary to some answers/comments here, what you are asking for would have a real use if it existed:
class Derived : Base
{
This can be seen by considering the workaround:
class Derived
{
private Base _base = new Base();
In other words, it's not really a base class at all, but a hidden part of the implementation.
The downside with this workaround is: what Base has an abstract method that you have to supply? You have to write this:
class Derived
{
class ActualDerived : Base
{
// override abstract method(s)
}
private Base _base = new ActualDerived();
This is the whole point of private inheritance (as found in C++) - it's for situations when you want to inherit the implementation but not the "interface" (in the informal sense).
But in C#, it's not available.
Presumabely A and B have something in common. Can you factor that out into a different base class?
public class Base
{
... common stuff ...
}
public class A : Base
{
public void Init()
{
}
}
public class B : Base
{
public void Init(int info)
{
}
}
if you need polymorphism then references to Base or, better yet, Thomas' interface are the way to go.
Instead of inheritance, use an interface as a "middle man":
public interface IAllThatYouNeed
{
public void DoSomeStuff();
}
public class A : IAllThatYouNeed
{
public void Init() {
// do stuff
}
}
public class B : IAllThatYouNeed
{
public void Init(int info) {
// do stuff
}
}
it looks like it's not yet possible
i tried to do something like this:
public class B : A
{
private override void Init() { }
public void Init(int x)
{ }
}
but Init() it's still visible from the A class
There is no perfect solution here. Some possible ways to do it:
An approach would be to make A.Init() virtual, override it in B and make it throw a NotImplementedException/InvalidOperationException.
Init() stays visible, but the user finds out very quickly that it is not to be used (make it explicit that Init(int info) is to be used in the XML documentation and in the message of the exception).
If you don't care about the inheritance part and just want to use the functionalities of class A in class B, don't have B deriving from A and make B instantiate A and use its functionalities.
Edit:
You can use an interface implementing the common operations in order to retain inheritance while avoiding to implement Init() in B:
public interface IOperations
{
void DoStuff();
void Foo();
}
public class A : IOperations
{
public void Init()
{
// Do class A init stuff
}
#region IOperations Members
public void DoStuff()
{
// ...
}
public void Foo()
{
// ...
}
#endregion
}
public class B : IOperations
{
A _operations = new A();
public void Init(int initData)
{
_operations.Init();
// Do class B init stuff
}
#region IOperations Members
public void DoStuff()
{
_operations.DoStuff();
}
public void Foo()
{
_operations.Foo();
}
#endregion
}
This can be made even better by using a factory:
public static class OperationsFactory
{
public static IOperations CreateOperations()
{
A result = new A();
result.Init();
return result;
}
public static IOperations CreateOperations(int initData)
{
B result = new B();
result.Init(initData);
return result;
}
}
This way instantiation code is well encapsulated, the difference between the two Init() methods is hidden from the user code.