I've encountred a confusing problem while developping a user library in c# in which i've created two classes that implement an interface that is called by the API as a separated plugin...
(that means that after the compilation the API detect 2 plugins although they are from same project)
What i'm trying to do is to enable communication between those two plugins. Accuratly i want to transfer an object (it's reference not a copy) from a plugin to another... but i'm failing!
I tried to make one of those plugins Singleton and reach it from the other, but since the API require a public constructor, I was forced to imitate the singleton work, and effectively i've reached the instance of the plugin, but i'm enable to reach its properties...
Let me schematize that through simplified code:
let's say this is class A (the one that imitate the singleton)
Class A:IPlugin
{
private static volatile A _instance;
public static A Instance
{
get { return _instance; }
}
public A()
{
if (_instance == null) _instance = this; // as i'm sure it's called once
}
public Foo F{get;set} // THIS IS INITIALIZED SOMEWHERE IN THAT PLUGIN'S CONTEXT
}
and this is the class that tries to extract objects from A
Class B:IPlugin
{
FindFoo()
{
Foo Fb = A.Instance.F; // THAT IS ALWAYS NULL
}
}
A very important indication and the one that may create the problem is that:
A.F is bound to a WPF control...
I hope I've clearly transmitted my issue and you'll be able to help me because i'm stuck !
Try the following ;
public interface IPlugin {
string Foo { get; set;}
}
public class A : IPlugin {
private static A _inslance { get; set;}
public static A Instance {
get {
if (_inslance == null){
_inslance = new A();
}
return _inslance;
}
}
public string Foo { get; set;}
}
public class B : IPlugin {
public string GetMeFooOfA {
get {
return A.Instance.Foo;
}
}
public string Foo { get; set;}
}
void Main()
{
A.Instance.Foo = "Test 123";
var b = new B();
Console.WriteLine(b.GetMeFooOfA);
}
You may want to look at a DI (Dependency Injection), such as Unity, Ninject, etc.. framework which would offer you a good platform to work on when you develop modular code
Related
I have multiple classes in the service layer of my app.
Let's say I need to access some method from AbcService.cs in my controller. Then, I need to access some method from XyzService.cs in the same controller. Then another.......For this, I would need to create an object of each Service class separately in the constructor. Also, if I needed to access these methods in another cntroller I would again have to create objects of AbcService, XyzService, etc. I want to have one instance that can give me access to methods of all service classes.
Something like:
generalService.AbcService.MethodName();
generalService.AbcService.MethodName();
How do I do this in the best possible way?
You can use inheritance and create a class that (eventually) inherits from all of them, thus inheriting their methods. Or you can make them inherit from each other (this way you'll have to use the service class that inherits from both, as it would have all the methods that can be inherited).
To put it very simply, it can go like this using inheritance (I assume the service classes were not inheriting from anything until now):
public class ServiceClassA
{
//Certain Methods
}
public class ServiceClassB : ServiceClassA
{
//Other methods, this class also has ServiceClassA methods
}
public class ServiceClassC : ServiceClassB
{
//Even more methods, this class also has ServiceClassA and ServiceClassB methods
}
//... and so on
Assuming the lowest class in the inheritance tree is ServiceClassC for example, you only need a ServiceClassC object and you'll be able to access the needed (inherited) methods.
Create service layer so that other componentns can access easily.
public class Program
{
static void Main(string[] args)
{
Global.ServiceABC.MethodA();
Global.ServiceXYZ.MethodB();
}
}
public class Global
{
private static ABC serviceABC;
public static ABC ServiceABC { get
{
if (serviceABC == null)
{
serviceABC = new ABC();
}
return serviceABC;
}
}
private static XYZ serviceXYZ;
public static XYZ ServiceXYZ
{
get
{
if (serviceXYZ == null)
{
serviceXYZ = new XYZ();
}
return serviceXYZ;
}
}
}
public class ABC
{
public void MethodA() { }
}
public class XYZ
{
public void MethodB() { }
}
Unfortunately in C# you can NOT inherit from two classes at once so something like
public class CombinedService : AbcService, XyzService {
}
is not possible.
You can however use static methods to have only one instance per service like this:
public static class ServiceManager {
// The variable holding the instance
private static AbcService _abcService = null;
// Access to the instance and single instance creator
public static AbcService AbcServiceInstance {
get {
if (_abcService == null) {
// Create your Instance here
_abcService = new AbcService();
}
return _abcService;
}
}
// The variable holding the instance
private static XyzService _xyzService = null;
// Access to the instance and single instance creator
public static XyzService XyzServiceInstance {
get {
if (_xyzService == null) {
// Create your Instance here
_xyzService = new XyzService();
}
return _xyzService;
}
}
}
Because they are static you can access them from everywhere in the code just by calling the static class properties like this:
ServiceManager.AbcServiceInstance.SomeMethod();
ServiceManager.XyzServiceInstance.SomeMethod();
You can also shorten the instantiation and accessor like this:
private static AbcService _abcService = new AbcService();
public static XyzService XyzServiceInstance {
get { return _abcService; }
}
If the instances can just be created like this and don't need any more parameters or configuration.
You should consider using a dependency injection container like Autofac. Register your service classes as Single Instance scope. You will get only one instance of a service class whenever you request it in every individual controller and even you do not need to create instance of it on your own.All is done by Ioc Container.
var builder = new ContainerBuilder();
builder.RegisterType<SomeService>().SingleInstance();
It somewhat depends how you choose to implement your services, but generally speaking you want some layer that encapsulate your services which is a singleton or that you inject\produce a single instance of it.
Encapsulation:
First try to look at a facade design pattern.
http://www.dofactory.com/net/facade-design-pattern
And btw if you don't need something complex and don't mind have an extra level of indirection then you can have some version of the facade like
KindOfSimpleFacade
{
public IServiceA ServiceA { get; }
public IServiceB ServiceB { get; }
}
Regarding the singleton there are a few ways to get it:
inject the facade object to the (just provide the same instance to each one of the controllers as an input).
(Facade) Factory -http://tutorialspoint.com/design_pattern/factory_pattern.htm
The factory will produce a single instance of the facade.
use static members inside the facade for example:
public class KindOfSimpleFacade
{
private static readonly serviceA = new ServiceA();
private static readonly serviceB = new ServiceB();
public IServiceA ServiceA { get { return serviceA; } }
public IServiceB ServiceB { get { return serviceB; } }
}
As the title suggests, it is possible to determine which instance of a class a particular instance of another class is instantiated from?
Update: Example Code below
class FooBar: Foo
{
private Context context;
public FooBar(Context _context): base(_context)
{
this.context = _context;
}
}
class Foo
{
public Baz baz;
private Context context;
public Foo(Context _context)
{
baz = new Baz();
this.context = _context;
}
}
class Baz
{
public Baz()
{
GetNameOfCaller()
}
private void GetNameOfCaller()
{
....
....
_className = ....;
}
private string _className;
}
Yes, you can do that for constructors the same way as for regular methods. Just use the CallerMemberName to pass in the name of the calling method. You won't have the class name with it, then you need to walk the StackTrace which is much more complicated.
public class X
{
public X([CallerMemberName] string caller = null)
{
this.Caller = caller;
}
public string Caller { get; private set; }
}
Then just call this. The compiler will fill in the caller parameter for you:
static void Main(string[] args)
{
X x = new X();
Console.WriteLine($"Caller = {x.Caller}"); // prints Main
}
You could use System.Diagnostics.StackTrace:
public class Foo
{
public void MethodBah()
{
System.Diagnostics.StackTrace t = new System.Diagnostics.StackTrace();
MethodBase callingMethod = t.GetFrame(1).GetMethod();
Type callingMethodType = callingMethod.DeclaringType;
string className = callingMethodType.Name;
}
}
Works even in .NET 1.1.
With your (updated) example you have to use t.GetFrame(2).GetMethod() instead of GetFrame(1) to get FooBar instead of Foo because the child- calls the parent constructor.
I believe that your requirement should be solved using aspect-oriented programming.
OP said in some comment:
[..] Logging purposes for now but may not be limited to it alone [...]
For example, there's an extremely powerful tool called PostSharp which lets you intercept any method call, when it's being called and after it was called:
[Serializable]
public class LogAspect : OnMethodBoundaryAspect
{
public override void OnEntry(MethodExecutionArgs args)
{
}
public override void OnExit(MethodExecutionArgs args)
{
}
}
Now you can apply the whole aspect as a regular attribute to a method, class or even to an assembly (thus, all methods within the assembly will be loggable).
You can access called method through MethodExecutionArgs.Method (which is of type MethodBase, and this means that you can access which type declares the whole method through MethodBase.DeclaringType.
With a tool like PostSharp you are adding an extra compilation step, but it has the great advantage that your interceptions are injected during compile-time. That is, it will perform like adding the whole code manually in every method.
You can also implement the same thing creating run-time proxies using Castle DynamicProxy to intercept method calls.
If I have a class (class P) which makes use of some other re-usable component (class C) (eg a state manager), then if that component needs to access some data within my top level class (P), then what choices do I have?
The key thing is that I dont want to expose this data to the outside world, just to within components I know and trust and use within P.
public static class Program
{
private void Main()
{
var owner = new Owner();
// I can call Foo()!!!
((IOwner)owner).Foo();
}
}
public interface IOwner
{
void Foo();
}
public class Owner : IOwner
{
private Component m_component;
public void SomeExternalAPI()
{
m_component = new Component(this);
m_component.DoSomething();
}
void IOwner.Foo()
{
// do something
}
}
public class Component
{
private readonly IOwner m_owner;
public Component(IOwner owner)
{
m_owner = owner;
}
public void DoSomething()
{
m_owner.Foo();
}
}
I could use an interface on P, but this then exposes the data externally.
I could use an explicit interface on P, but this can be cast and so also easily exposes the data.
If I could somehow impart "Friendship" upon the component (which I created, and ideally at the instance level!), and make IOwner a friend-only interface then, it would be secure.
I know this is impossible in C# at the moment.
It comes up quite often for me.
Has anyone got any solutions or suggestions?
You can use the internal accessor on your interface and Component class.
internal interface IOwner
{
void Foo();
}
internal class Component
{
private readonly IOwner m_owner;
public Component(IOwner owner)
{
m_owner = owner;
}
public void DoSomething()
{
m_owner.Foo();
}
}
The Owner class would be public
public class Owner : IOwner
{
private Component m_component;
public void SomeExternalAPI()
{
m_component = new Component(this);
m_component.DoSomething();
}
void IOwner.Foo()
{
// do something
}
}
With this approach, you won't be able to access the interface nor the Component class from an external assembly
The client would only see the Owner class and its SomeExternalAPI() method.
var Owner = new Owner();
owner.SomeExternalAPI();
//owner.Foo() --> Won't compile!
//((IOwner)owner).Foo() --> Won't compile!
I think I've found a reasonable solution, altho its quite hard work and more code than I'd like
Use a proxy class, which implements the public IOwner interface, but which can then call into the actual owner using an internal IInternalOwner interface, which it was given on construction.
The proxy then acts like a token allowing the owner to be called by anyone it gives this token to. Its more code than I would like, and it would be nice if this was built into C# :-).
But, it works between assemblies (in fact I had 4 to test it!).
public class Owner : IInternalOwner
{
private ITheComponent m_component;
public void SomeExternalAPI()
{
var proxy = new Proxy(this);
m_component = ClassFactory.ConstructTheComponent(proxy);
m_component.DoSomething();
}
void IInternalOwner.Foo()
{
// do something
Console.WriteLine("Owner.Foo was called");
}
private class Proxy : IOwner
{
private IInternalOwner m_owner;
public Proxy(IInternalOwner owner)
{
m_owner = owner;
}
/// <summary>
/// pass through for each method & property!
/// </summary>
public void Foo()
{
m_owner.Foo();
}
}
}
internal interface IInternalOwner
{
void Foo();
}
I've got something like this:
// This gets implemented by plugin authors to get callbacks about various things.
public interface ExternalPlugin
{
// This gets called by the main application to tell the plugin some data
// is available or similar.
void DoStuff(SomeDataBlob blob);
}
// Data blob for v1 of API
public class SomeDataBlob
{
internal SomeDataBlob(string prop) { Prop = prop; }
// Some piece of data that V1 plugins need
public string Prop { get; private set; }
}
// FUTURE!
// Data blob API v2 of API
public class SomeDataBlobV2 : SomeDataBlob
{
// Can be passed to clients expecting SomeDataBlob no problem.
internal SomeDataBlobV2(string prop, string prop2) :base(prop) { Prop2 = prop2; }
// Some piece of data that V2 plugins need. V2 plugins can cast to this from
// SomeDataBlob, but still can load successfully into older versions that support
// only V1 of the API
public string Prop2 { get; private set; }
}
I have to make SomeDataBlob public so that it can be used as a member of the public interface method ExternalPlugin.DoStuff. However, I would not like to allow clients to inherit from that class and thus be susceptible to the brittle base class problem. (All derivatives of that class should be kept in the same assembly)
Marking the class sealed goes too far because I believe removing sealed is a breaking API change; and even if that isn't, once I ship SomeDataBlobV2 clients could still do the wrong thing and inherit from SomeDataBlob directly.
Is there a way to enforce this kind of pattern?
Make the class internal, and expose an interface instead. Then use the factory pattern to create the correct implementation.
public interface ISomeDataBlob
{
}
internal class SomeDataBlob : ISomeDataBlob
{
}
public class BlobApiFactory
{
ISomeDataBlob Create();
}
You hide the implementation, but still give the user access to everything. You even make unit tests easier for your users ;)
Edit (answer to a comment from the OP)
What I effectively want is some method taking some parameters. I want to be able to add parameters that the main application can provide in a future version if the API without breaking clients. But I don't want clients to be able to create instances of the "parameters" class/interface or otherwise interact with it beyond receiving an instance of it as a parameter
Instead of hiding the APIs you can make sure that all object passed to your library originates from your assembly:
public class YourCoolService
{
public void DoSomething(ISomeDataBlob blob)
{
if (blob.GetType().Assembly != Assembly.GetExecutingAssembly())
throw new InvalidOperationException("We only support our own types");
}
}
Edit2
Just noticed that #RQDQ already provided that solution (didn't notice when answering your comment). If that's the solution you want, accept his answer instead.
/// <summary>
/// This is a dummy constructor - it is just here to prevent classes in other assemblies
/// from being derived from this class.
/// See http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2971840&SiteID=1
/// </summary>
internal MhlAdminLayer() { }
The idea is to have a constructor with no parameters internal. Then the class can't be derived from.
Edit: Sorry, the link in the comment doesn't work any more.
Edit 2:
http://msdn.microsoft.com/en-us/library/vstudio/ms173115.aspx
"You can prevent a class from being instantiated by making the constructor private ... "
If you are hell bent on not using sealed AND still using classes, you can enforce this at runtime. In otherwords, at your API boundary, inspect the classes involved and make sure they come from your assembly.
A simple example:
public void Bar(Foo foo)
{
if (foo.GetType().Assembly != this.GetType().Assembly)
throw new InvalidOperationException("It's not one of mine!");
}
public class Foo
{
}
As far as I know, interfaces are the way to do this. It would be an API breaking change, but it would mean you could do what you want.
public interface ExternalPlugin
{
void DoStuff(ISomeDataBlob blob);
}
// Interfaces:
public interface IDataBlob
{
string Prop { get; }
}
public interface IDataBlobV2 : IDataBlob
{
string Prop2 { get; }
}
// Data blob for v1 of API
internal class SomeDataBlob : IDataBlob
{
internal SomeDataBlob(string prop) { Prop = prop; }
public string Prop { get; private set; }
}
// FUTURE!
// Data blob API v2 of API
public class SomeDataBlobV2 : SomeDataBlob, IDataBlobV2
{
// Can be passed to clients expecting SomeDataBlob no problem.
internal SomeDataBlobV2(string prop, string prop2) : base(prop) { Prop2 = prop2; }
public string Prop2 { get; private set; }
}
And then to make the objects use the factory pattern, e.g.
public static class DataBlobFactory
{
public IDataBlob GetDataBlob(string prop)
{
return new SomeDataBlob(prop);
}
// so on.
}
What I would do is make some sort of factory class that exposes an interface that would pass an instance of whatever version for the specific API your client is using, and hide the implementation with an internal class
You can also use constraints to make it little easier to use, then the client can just put the Type of object they are looking for
public interface IBlobV1 { /*public stuff for V1 here*/ }
internal class BlobV1: IBlobV1 {/*v1 implementation*/ }
public interface IBlobV2 : IBlobV1 {/*public interface for V2 here*/ }
internal class BlobV2:BlobV1,IBlobV2 {/*v2 implementation*/}
public sealed BlobFactory
{
public IBlobV1 CreateVersion1Blob(){/* implementation */}
public IBlobV2 CreateVersion2Blob(){/* implementation */}
public T CreateBlob<T>()
where T: IBlobV1
{ /* implementation */}
}
SomeDataBlob can not be inherited because its only constructor is internal. If you try to implement a derived class in a client application:
class SomeDataBlobClient : SomeDataBlob
{
SomeDataBlobClient():base("TEST")
{
}
}
You will get the following error:
The type 'ClassLibrary1.SomeDataBlob' has no constructors defined
It seems that you solved your own problem.
//Found the solution...
The problem was in fact that I have an array of register filled on creation (contructor method) and that array wasn't instanciated.
To make it short, I've been too noob to even put a break point in the constructor to see if .Net handled a first chance exception.
Thanks again for all the repliers. You have been really helpful. :)
Sorry again for my noobness
What have I learned today :
-You never know how .net will merge your partial class
-Be more aware of first chance exceptions
//STATE CHANGE 2012/01/30 17:00 or so
Sorry, I narrowed on the wrong problem. The problem explained here doesn't seem to be caused by the code provided therefore this question no longer needs to exist.
Thanks to the repliers!
//DEPRECATED, CLOSED ... W/E
I have a device which can be contacted by various registry such 0x01, 0x02, 0x03...
Also, I work in a development environment and the application I produce are oriented for our own environment in a small compagny.
To turn these registry into object I have chosen, a long time ago, to make a class which have it's constructor private to create it's own and only instance (As I understand, multi-ton design pattern).
Since there's a lot of registry now and the class file is getting huge I want to split it into parts : The property/function definitions and the multi-ton objects.
When I try to use this ex:
Register.cs :
namespace DeviceManagement.Register
{
public partial class Register
{
public int id { get; private set; }
public string foo { get; private set; }
public string bar { get; private set; }
protected Register(RegisterEnum id, string foo, string bar)
{
this.id = (int)id;
this.foo = foo;
this.bar = bar;
}
}
}
Register.enum.cs :
namespace DeviceManagement.Register
{
public partial class Register
{
protected enum RegisterEnum
{
reg1 = 0x01,
reg2 = 0x02 //and so on
};
}
}
Register.const.cs :
namespace DeviceManagement.Register
{
public partial class Register
{
public static readonly Register reg1 =
new Register(RegisterEnum.reg1,"foo1","bar1");
public static readonly Register reg2 =
new Register(RegisterEnum.reg2,"foo2","bar2");
//there is plenty more
}
}
I intended to use it like
namespace DeviceManagement
{
class SomeClassA
{
public void doThisOnDevice(Device device)
{
device.doSomeStuffOn(Register.Register.reg1, SomeCommonlyUsedStrategy);
}
}
}
Here's a test I did :
namespace DeviceManagement
{
class SomeClassA
{
public void testIfNull()
{
if(Register.Register.reg1 == null)
MessageBox.Show("It is null");
}
}
}
The compilator, intellisense doesn't throw any error/warning but, when I run my project, the Register objects are never instanciated. Altough, I don't have that issue when all this code is in the same class (not partial) and obviously in the same file.
I'm kind of lost, please help me.
For starters you don't need to break it out into a partial class to have it over multiple files. If you want to lump it together then you can put it in a different sub namespace in separate files, anyway ...
It looks like a namespace issue, as you need to have Register.Register.reg1 to access the static const.
EDIT
Ok, so from the feedback and re-reading the question a few more times I get the feeling that the current design probably won't quite work all in the same class definition. I think you maybe trying to force something into some thing which won't go.
So, why not try something like this:
namespace DeviceManagement.Register
{
public class Register
{
public RegisterType Type { get; private set; }
public string Foo { get; private set; }
public string Bar { get; private set; }
public Register(RegisterType type, string foo, string bar)
{
Type = type;
Foo = foo;
Bar = bar;
}
}
public enum RegisterType
{
reg1 = 0x01,
reg2 = 0x02 //and so on
}
public static class RegisterFactory
{
private static readonly Dictionary<RegisterType, Register> _dictionary = new Dictionary<RegisterType, Register>
{
{ RegisterType.reg1, new Register(RegisterType.reg1, "foo", "bar") },
{ RegisterType.reg2, new Register(RegisterType.reg2, "foo2", "bar2") }
};
public static Register GetRegister(RegisterType type)
{
return _dictionary[type];
}
}
}
And consume the register:
public class SomeClassA
{
public void DoThisOnDevice(Device device)
{
device.DoSomeStuffOn(RegisterFactory.GetRegister(RegisterType.reg1), SomeCommonlyUsedStrategy);
}
}
You could then take it a step further and load in the registry details from a configuration file which parses it on start up of your application to, you could then choose the registry type to work on from your UI etc.
Hope I've not got the wrong end of the stick.
I copy pasted your code and it works fine for me.
My advice is to use the Class View of Visual Studio. Here you can easily see if all the partial classes are defined within the same namespace and with the exactly same class name. If not, too many namespaces or classes will appear.