For a library (.NET Standard 2.0), I designed some classes that look roughly like this:
public class MyContext
{
// wraps something important.
// It can be a native resource, a connection to an external system, you name it.
}
public abstract class Base
{
public Base(MyContext context)
{
Context = context;
}
protected MyContext Context { get; private set; }
// methods
}
public class C1 : Base
{
public C1(MyContext context, string x)
: base(context)
{
// do something with x
}
// methods
}
public class C2 : Base
{
public C2(MyContext context, long k, IEnumerable<C1> list)
: base(context)
{
// do something with the list of C1s.
}
// methods
}
public class C3 : Base
{
public C3(MyContext context, int y, double z)
: base(context)
{
// do something with y and z.
}
public void DoSomething()
{
var something = new C2(this.Context, 2036854775807, new[]
{
new C1(this.Context, "blah"),
new C1(this.Context, "blahblah"),
new C1(this.Context, "blahblahblah"),
}
);
}
// other methods
}
// other similar classes
The classes were criticized because of that "MyContext" parameter that every constructor requires.
Some people say that it clutters the code.
I said that the parameter is needed to propagate the context, so that e.g. when you call the DoSomething method of C3, the contained instances of C1 and C2 all share the same context.
A potential alternative is defining the parameter as Base instead of MyContext, e.g.:
public abstract class Base
{
public Base(Base b) // LOOKS like a copy constructor, but it isn't!
{
Context = b.Context;
}
protected MyContext Context { get; private set; }
// methods
}
public class C1 : Base
{
public C1(Base b, string x)
: base(b)
{
// do something with x
}
// methods
}
public class C2 : Base
{
public C2(Base b, long k, IEnumerable<C1> list)
: base(b)
{
// do something with the list of C1s.
}
// methods
}
public class C3 : Base
{
public C3(Base b, int y, double z)
: base(b)
{
}
public void DoSomething()
{
var something = new C2(this, 2036854775807, new[]
{
new C1(this, "blah"),
new C1(this, "blahblah"),
new C1(this, "blahblahblah"),
}
);
}
// other methods
}
// other similar classes
Now the parameter you must pass is shorter, but it still raised some eyebrows.
(And I don't like it very much, because logically a C1/C2/C3/etc object does not require a Base, it requires a MyContext. Not to mention that constructor that seems a copy constructor, but it is not! Oh, and now how can I initialize C1, C2 or C3 outside a Base-derived class, since all of them want a Base, and Base is abstract? I need to "bootstrap" the system somewhere... I guess all classes may have two constructors, one with Base and one with MyContext ... but having two constructors for each class may be a nightmare for future maintainers...).
Some people said "Why don't you turn MyContext into a singleton, like in Project X?".
Project X has a similar class structure but, "thanks" to the singleton, classes don't have a MyContext parameter: they "just work". It's magic!
I don't want to use a singleton (or static data in general), because:
singletons are actually global variables, global variables are a bad programming practice. I used global variables many times, and many times I regretted my decision, so now I prefer to avoid global variables if possible.
with a singleton, classes share a context, but only ONE context: you cannot have MULTIPLE contexts. I find it too limiting for a library that will be used by an unspecified number of people in the company.
Some people said that we should not be too anchored to "academic theory", useless ideas of "good" and "bad" programming practices, that we should not overengineer classes in the name of abstract "principles".
Some people said that we should not fall into the trap of "passing around ginormous context objects".
Some people said YAGNI: they're pretty sure that 99% of the usage will involve exactly one context.
I don't want to anger that 1% by disallowing their use case, but I don't want to frustrate the other 99% with classes that are difficult to use.
So I thought about a way to have the cake and eat it.
For example: MyContext is concrete but it ALSO has a static instance of itself. All classes (Base, C1, C2, C3, etc) have two constructors: one with a MyContext concrete parameter, the other one without it (and it reads from the static MyContext.GlobalInstance).
I like it... and at the same time I don't, because again it requires to maintain two constructors for each class, and I'm afraid it can be too error-prone (use the incorrect overload just once and the entire structure collapses, and you find out only at runtime).
So forget for the moment the "static AND non static" idea.
I tried to imagine something like this:
public abstract class Base
{
public Base(MyContext context)
{
Context = context;
}
protected MyContext Context { get; private set; }
public T Make<T>(params object[] args) where T : Base
{
object[] arrayWithTheContext = new[] { this.Context };
T instance = (T)Activator.CreateInstance(typeof(T),
arrayWithTheContext.Concat(args).ToArray());
return instance;
}
// other methods
}
public class C1 : Base
{
public C1(MyContext context, string x)
: base(context)
{
// do something with x
}
// methods
}
public class C2 : Base
{
public C2(MyContext context, long k, IEnumerable<C1> list)
: base(context)
{
// do something with the list of C1s.
}
// methods
}
public class C3 : Base
{
public C3(MyContext context, int y, double z)
: base(context)
{
// do something with y and z.
}
public void DoSomething()
{
var something = Make<C2>(2036854775807, new[]
{
Make<C1>("blah"),
Make<C1>("blahblah"),
Make<C1>("blahblahblah"),
}
);
}
// other methods
}
// other similar classes
The calls to Make LOOK better, but they are even more error-prone, because the signature of Make is not strongly-typed. My goal is to simplify doing stuff for the users. If I opened a parenthesis and Intellisense proposed me ... an array of System.Object, I'd be VERY frustrated. I could pass incorrect parameter and I would find out only at runtime (Since good old .NET Framework 2.0, I hoped to forget about arrays of System.Object...)
So what? A factory with a dedicated, strongly-typed method for each Base-derived class would be type-safe, but maybe it would also be "ugly" to see (and a textbook violation of the open-close principle. Yes, "principles", again):
public class KnowItAllFactory
{
private MyContext _context;
public KnowItAllFactory(MyContext context) { _context = context; }
public C1 MakeC1(string x) { return new C1(_context, x); }
public C2 MakeC2(long k, IEnumerable<C1> list) { return new C2(_context, k, list); }
public C3 MakeC3(int y, double z) { return new C3(_context, y, z); }
// and so on
}
public abstract class Base
{
public Base(MyContext context)
{
Factory = new KnowItAllFactory(context);
}
protected MyContext Context { get; private set; }
protected KnowItAllFactory Factory { get; private set; }
// other methods
}
public class C1 : Base
{
public C1(MyContext context, string x)
: base(context)
{
// do something with x
}
// methods
}
public class C2 : Base
{
public C2(MyContext context, long k, IEnumerable<C1> list)
: base(context)
{
// do something with the list of C1s.
}
// methods
}
public class C3 : Base
{
public C3(MyContext context, int y, double z)
: base(context)
{
// do something with y and z.
}
public void DoSomething()
{
var something = Factory.MakeC2(2036854775807, new[]
{
Factory.MakeC1("blah"),
Factory.MakeC1("blahblah"),
Factory.MakeC1("blahblahblah"),
}
);
}
// other methods
}
// other similar classes
EDIT (after the comments): I forgot to mention that yes, someone suggested me about using a DI/IoC framework like in "Project Y". But apparently "Project Y" uses it only to decide if instantiate MyConcreteSomething or MyMockSomething when ISomething is needed (please consider mocking and unit tests out of scope for this question, because reasons), and it passes around the DI/IOC framework objects exactly like I pass around my context...
Of the alternatives listed in OP, the original one is the best. As the Zen of Python states, explicit is better than implicit.
Using a Singleton would make an explicit dependency implicit. That doesn't improve usability; it makes things more unclear. It makes the API harder to use because there's more things a user of the API would have to learn before he or she could use it successfully (as opposed to just looking at the constructor signature and supplying the arguments that makes the code compile).
It doesn't really matter whether the API requires a few more keystrokes to use. In programming, typing isn't a bottleneck.
Passing MyContext via the constructor is just plain old Constructor Injection, even if it's a concrete dependency. Don't let the Dependency Injection (DI) jargon fool you, though. You don't need a DI Container to use those patterns.
What you might consider as an improvement is to apply the Interface Segregation Principle (ISP). Does the base class need an entire MyContext object? Could it implement its methods with only a subset of MyContext's API?
Does the base class need MyContext at all, or is it only there for the benefit of derived classes?
Do you even need a base class?
In my experience, you can always come up with a better design that doesn't use inheritance. I don't know what it'd be in this case, but how about something like the following?
public class C1
{
public C1(MyContext context, string x)
{
// Save context and x in class fields for later use
}
// methods
}
public class C2
{
public C2(MyContext context, long k, IEnumerable<C1> list)
{
// Save context, k, and the list of C1s in class fields for later use
}
// methods
}
public class C3
{
public C3(MyContext context, int y, double z)
{
Context = contex;
// do something with y and z.
}
public MyContext Context { get; }
public void DoSomething()
{
var something = new C2(this.Context, 2036854775807, new[]
{
new C1(this.Context, "blah"),
new C1(this.Context, "blahblah"),
new C1(this.Context, "blahblahblah"),
}
);
}
// other methods
}
Whether or not you have a base class makes no difference when it comes to reusing a single instance of MyContext. You can still do this even if these three classes have no common supertype.
I am new to Dependency injection Pattern. Please look in to the below scenario. Right now, my below code is in tightly coupled. I want to make this as lightly coupled.
Could someone help me out to implement dependency injection using Unity?
// Implementation of class A
public class A
{
public B b{get;set;}
public A(B b,string c)
{
this.b=b;
this.A(b,c);
}
}
//Implementation of Class B
public class B
{
public int value1 {get;private set;}
public string stringValue {get;private set;}
public B(int value,string strValue)
{
this.value1=value;
this.stringValue=strValue;
}
}
//Implementation of class C
public class C
{
public void Dosomething()
{
B b=null;
string value="Something";
// Here I need to implement unity to resolve tight coupling
// without creating object of Class A
A a=new A(b,value);
}
}
I tired something based on the blow possible duplicate question. But still I am facing same issue.
How should I register this type that has parameterized constructor, in Unity?
Instead of this line, I have implemented the below code
A a=new A(b,value);
var container=new UnityContainer();
container.RegisterType<A>();
container.RegisterType<B>();
A a=new A(b,container.ResolveType<B>();
But its not helping me out.
Firstly, I would start be advising that you further decouple your classes by introducing Interfaces, so you could implement class C as follows:
public class C
{
private readonly IA a;
private readonly IB b;
public C(IA a, IB b)
{
this.a = a;
this.b = b;
}
public void Dosomething()
{
// do something with this.a or this.b.
}
}
You could then register and resolve your classes as below:
var container = new UnityContainer();
container.RegisterType<IB, B>(new InjectionConstructor(1, "Test"));
container.RegisterType<IA, A>(new InjectionConstructor(new ResolvedParameter<IB>(),"Test"));
container.RegisterType<IC, C>();
var c = container.Resolve<IC>();
Although I would recommend the above approach, as an alternative, you can also stipulate the injection values when you resolve, for example:
container.RegisterType<IB, B>();
container.Resolve<IB>(
new ParameterOverride("value", 1),
new ParameterOverride("strValue", "Test"));
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?
class A implements IC
class B implements IC
class Factory has a method GetObject(int x); x=0 for A, x=1 for B.
How can I force the usage of Factory.GetObject method to create objects of type A and B and prevent something like new A(), which should be Factory.GetObject(0)?
How can I force the usage of Factory GetObject method to create objects of type A and B and prevent something like new A()
You can't force the usage of Factory.GetObject, this is something that you should write in the documentation of the API you are providing after marking A and B constructors internal.
public class A: IC
{
internal A() { }
}
public class B: IC
{
internal B() { }
}
public static class Factory
{
public static IC GetObject(int x)
{
if (x == 0)
{
return new A();
}
if (x == 1)
{
return new B();
}
throw new ArgumentException("x must be 1 or 2", "x");
}
}
This way those constructors will not be accessible from other assemblies. Also don't forget about Reflection which will allow for direct instantiation of those classes no matter how hard you try to hide them.
I'm not sure if it's still relevant (it's been a year...) but here's how you can achieve further enforcement of the factory usage:
public class A
{
internal protected A() {}
}
public class AFactory
{
public A CreateA()
{
return new InternalA();
}
private class InternalA : A
{
public InternalA(): base() {}
}
}
Components using class A cannot directly create it (so long they don't inherit it...).
So I've got a class like this:
public class A {
internal A(int i) { ... }
public int Foo { get; set; }
}
This class is then inherited by a bunch of generated classes, eg:
public class B : A {
...
}
The int based constructor isn't exposed to the inherited class (for design reasons I don't want it exposed). In my library which holds the definition for class A I've got a method like this:
public T Load<T>() where T : A {
//do some stuff, create an instance of T from an int, then return it
}
And then I'd use it like this:
B b = Helper.Load<B>();
Since the constructor I want to use isn't exposed to class B when I do typeof(T).GetConstructor(typeof(int)) I don't get the constructor back, so I want thinking that I'd do this:
return (T)new A(/*some int */);
But that gives me a runtime error System.InvalidCastException, that I can't cast a type A to type B.
How do I go about achieving this upcasting?
You can just use default constructors so you can instantiate objects of type T with the new() constraint. Then class A can have a virtual (or abstract to your liking) method that takes an int as an argument and initializes the object after the constructor has run.
public class A {
internal A() { }
internal Initialize(int i) { Foo = i; }
public int Foo { get; set; }
}
public class B : A {
internal B() { }
}
...
public T Load<T>() where T : A, new() {
var ret = new T();
ret.Initialize(i);
return ret;
}
If you intend some sort of factory pattern, you don't need to hesitate initializing parts of an object outside the constructor call as long as it is done before you return the object to the caller's control.
From what I understood, T derives from A, so you can't cast A to T.
You can't upcast A to B in your example, because:
return (T)new A(/*some int */);
Instantiates an A, which is not a B. Just because a "B is an A" does not mean "A is a B". You would have to first instantiate a B, cast it to an A, do what you want, and then upcast it back to a B.
I'm not sure if this is will compile, but you could try this:
T blah = new T(5); //this means your B will need to implement a int constructor
A blah2 = (A)blah;
//operate on A specific operations in blah2
T upcasted = (T)blah2;
//alternatively
T upcasted = blah2 as T;
Consider refactoring your contructor such that you initialize the integer as a property, instead of a parameter of the constructor. I strive to have default(no parameters) contructors so that generic code can instantiate the class easily.
You cant do this, change your design.