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...).
Related
Let's suppose there is a following class:
public class foo{
internal virtual object M1(/*args*/){return null;}
internal virtual object[] M2(/*args*/){return null;}
public SomeStruct SomeMethod(){
return new SomeStruct
{
Obj = M1();
ObjArr = M2();
}
}
}
Using the following struct:
public class SomeStruct
{
public object Obj;
public object[] ObjArr;
}
Is there a way to make sure (preferably at compilation) to force either at least one method or exactly one method of class foo to be overriden?
Before anybody says it - I know it's possible to use one method and check if the result is array (or IEnumerable) and then assign it to the right field, but that takes more time then just running empty methods. I'm just wondering if it's possible to do it that way.
You could mark the methods abstract, and then you will be forced to implement both of the methods. This seems to be the most straightforward solution:
internal abstract object M1(/*args*/){return null;}
internal abstract object[] M2(/*args*/){return null;}
Another option, actually too complicated for this purpose, is to write a Roslyn code analyzer which will check the code and determines if it is valid.
As a side note: your fields should reside in the base class too. You could use generics if you want to make the types of them generic.
"No", basically. At least, not without writing your own custom code analyzer (perhaps via Roslyn), and considering what happens if X : foo overrides M1, and Y : X overrides M2.
You need to create a new method in your child class that hides the implementation of the base class, with the new return type. You cannot use virtual methods to overload a method like you're doing.Overloading of methods is done by changing the parameters, not the return type.
So either hide the parent method, in the child class, or create a method with another name.
Here is something that I can think of, just an example.
Run it here .Net Fiddle
using System;
public class a
{
public virtual object s(int a)
{
return a + 1;
}
}
public class b : a
{
public virtual object[] s(int a)
{
var arr = new object[]{a + 2};
return arr;
}
}
public class c : b
{
private a A = new a();
private b B = new b();
public c()
{
print(2);
}
public void print(int a)
{
var result = A.s(1);
Console.WriteLine("result : " + result);
var resultB = B.s(1);
//or resultB = base.s(1);
foreach (var r in resultB)
{
Console.WriteLine("result B : " + r);
}
}
}
public class Program
{
public static void Main()
{
c C = new c();
}
}
I just came up with a really odd problem and I wasn't able to figure out how to solve it.
I have 3 classes, the class A is the base for B and C, that is:
class A { ... }
class B : A { ... }
class C : B { ... }
Now I would like to have a static property in these classes that stores the last object of each classes created, for example:
class A
{
static public A lastInstance;
}
class B : A
{
public B()
{
lastInstance = this;
}
}
class C : A
{
public C()
{
lastInstance = this;
}
}
What I would like to achieve is to be able to retrieve an instance for each subclass, for example:
var v1 = new B();
var v2 = new C();
var v3 = B.lastInstance; // v3 == v1 and v3 != v2
var v4 = C.lastInstance; // v4 == v2 and v4 != v3
Is it possible anyhow?
The only approach that seems promising to me shown in C# Static instance members for each inherited class: is it really the only chance I have to avoid defining a static member manually for each class?
I think this could be done with Dictionary and that's the only way i can think of right now:
class A {
static Dictionary<Type, A> _LastInstances = new Dictionary<Type, A>(); // because every subclass will inherit from A
public static A LastInstance {
get {
if ( _LastInstances.ContainsKey(GetType()) ) {
return _LastInstances[GetType()];
}
return null;
}
protected set {
if ( _LastInstances.ContainsKey(GetType()) ) {
_LastInstances[GetType()] = value;
} else {
_LastInstances.Add(GetType(), value);
}
}
}
class B : A {
public B(){
LastInstance = this;
}
}
At first: yes you can. But you missed two points with your implementation.
As you declared the lastInstance as public in class A every derived class can use it. As you declared it as static every instance of A will copy itself into it. But so will every instance of B, C and every other class with id derived from A: they all use the same instance. Thus the last instatiated class is saved and everything instantiated before is overwritten.
To overcome this, you must have a static property LastInstance (I switched to my naming convention) on every class, which you can accomplish by using the new modifier on derived classes
public class A
{
public static A LastInstance { get; private set; }
...
}
public class B : A
{
public static new B LastInstance { get; private set; }
...
}
But you're not done with that alone, because
When you create a new instance of B the (default-)construstor first makes a call into the construtor of A. Thus a reference to any already created instance of a base class is overwritten by the currently created instance of the derived class. So your constructors should look like this:
public class A
{
public static A LastInstance { get; private set; }
public A()
{
if (this.GetType() == typeof(A))
{
LastInstance = this;
}
}
}
public class B : A
{
public static new B LastInstance { get; private set; }
public B()
{
if (this.GetType() == typeof(B))
{
LastInstance = this;
}
}
}
This way you will get the correct lastly created instance (if any) in each classes static LastInstance.
Hope this helps
Because static members aren't inherited, you won't be able to access B.lastInstance if class A defines lastInstance. The suggestion you linked to seems reasonable. Although I don't have enough information on why you're attempting this, you could consider using a factory class that holds onto the latest created object.
Here's an example. This is not a good long term solution if you plan to have many classes deriving from A.
class HoldLastKnownFactory
{
B CreateB() { ... }
C CreateC() { ... }
B LastB { get {...} }
C LastC { get {...} }
}
I have two classes Say A and B which has method set().
public Class A : I<string>
{
void Set(string str)
{
//do something
}
}
public Class B : I<int>
{
void Set(int str)
{
//do something
}
}
And an interface as follows...
interface I<T>
{
void Set(T param);
}
I would like to access this method without instantiating the classes, through interface (Is it possible or is there any other way like dependency injection?).
From another Class
Class D
{
I.Set(<T> str); //something like this
}
So based on data type I need to redirect the call from either interface or some where, so that if tomorrow I added a class say C which implements same interface, I should not end up with changing code in D.
Thanks in Advance...
An interface is sort of like a template of methods an implementing class provides. You can not "do anything" with an interface. You always need an instance of a class implementing the interface.
So what you want does not work. However, a simple extension method will help you here:
public static class MyExtensionMethods
{
public static void SetValue<T>(this I<T> intf, T value)
{
intf.Set(value);
}
}
Using this, you can write:
A a = new A();
B b = new B();
b.SetValue("Hello");
a.SetValue(1);
And it will work for any other classes that implement I<T> without having to change the extension method:
public class D : I<double>
{
public void Set(double d) { ... }
}
D d = new D();
d.SetValue(42.0);
You need to pass in something, so at the moment, my best guess would be
class D
{
public void Set<T>(object target, T value)
{
var instance = target as I<T>;
if (instance != null)
{
instance.Set(value);
}
}
}
Called like:
var theD = new D();
var theA = new A();
var theB = new B();
theD.Set<string>(theA, "hello");
theD.Set<int>(theB, 1);
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();
}
}