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; } }
}
Related
I'm new to DI (using Ninject) and just started to learn the concepts, but I've been scratching my head for a while to understand this:
Suppose I have DIFFERENT usage of the same class in my program (ProcessContext in the example below).
In the first class (SomeClass) : I would like to inject Implement1 to ProcessContext instance.
In the second class (SomeOtherClass) : I would like to inject Implement2 to ProcessContext instance.
How should I perform the bindings using Ninject ?
public class Implement1 : IAmInterace
{
public void Method()
{
}
}
public class Implement2 : IAmInterace
{
public void Method()
{
}
}
public class ProcessContext : IProcessContext
{
IAmInterface iamInterface;
public ProcessContext(IAmInterface iamInterface)
{
this.iamInterface = iamInterface;
}
}
public class SomeClass : ISomeClass
{
public void SomeMethod()
{
// HERE I WANT TO USE: processcontext instance with Implement1
IProcessContext pc = kernel.Get<IProcessContext>();
}
}
public class SomeOtherClass : ISomeOtherClass
{
public void SomeMethod()
{
// HERE I WANT TO USE: processcontext instance with Implement2
IProcessContext pc = kernel.Get<IProcessContext>();
}
}
You could use named bindings for this.
e.g. something like:
Bind<IProcessContext>()
.To<ProcessContext>()
.WithConstructorArgument("iamInterface", context => Kernel.Get<Implement1>())
.Named("Imp1");
Bind<IProcessContext>()
.To<ProcessContext>()
.WithConstructorArgument("iamInterface", context => Kernel.Get<Implement2>())
.Named("Imp2");
kernel.Get<IProcessContext>("Imp1");
You can inject additional constructor parameters easily in this way:
public void SomeMethod()
{
var foo = new Ninject.Parameters.ConstructorArgument("iamInterface", new Implement2());
IProcessContext pc = kernel.Get<IProcessContext>(foo);
}
For now, I don't have access to ninject. So tell me if it doesn't work as expected.
This is not possible as Ninject has no way of knowing which implementation to return. However; if you create a new instance of your IProcessContext by passing in a variable then Ninject will look for the implementation with the appropriate constructor and return that one.
I have a requirement where only one instance of BillLines is ever created, which is of course perfect for the singleton pattern.
Looking at Jon's Skeet's post I'm not quite understanding where I create my 'new' object (i.e. the useful object not some abstract Singleton object).
Does this appear correct to you?
public sealed class ContextSingleton
{
private static readonly Lazy<ContextSingleton> Lazy =
new Lazy<ContextSingleton>(() => new ContextSingleton());
public static ContextSingleton Instance { get { return Lazy.Value; } }
private ContextSingleton()
{
}
//Is this correct? Where should I 'new' this?
public readonly IBillLineEntities Context = new BillLines.BillLines();
}
Being accessed like this:
var contextSingleton = ContextSingleton.Instance.Context;
Update
I don't have access to the internals of BillLines but I need to ensure only one instance of it exists.
I assume BillLines should be your Instance variable.
It should look like this:
public static class ContextSingleton
{
private static readonly Lazy<BillLines> _instance =
new Lazy<BillLines>(() => new BillLines());
public static BillLines Instance { get { return _instance.Value; } }
private ContextSingleton()
{
}
}
And you use it like this:
ContextSingleton.Instance
Edit
This answer was targeting the creation of a singleton about a specific class. If other people have access to your BillLines class and can create their own instance of it, then you should probably rethink what you're trying to do. If you do control the exposure of your BillLines class, you should make it so it is only exposed in the internal implementation of the singleton you're exposing, so no other person can create a new BillLines as they see fit.
Something simple like this?
public class BillLines
{
private BillLines()
{
}
private static BillLines _billLines = null;
public static BillLines Instance
{
get
{
if (_billLines == null)
_billLines = new BillLines();
return _billLines;
}
}
}
Thanks to the comments from #JonSkeet and #RobH I went down the dependency injection route. I picked Ninject and this does the job as I expected:
public class NinjectBindings : NinjectModule
{
public override void Load()
{
Bind<IBillLineEntities>.To<BillLines.BillLines>().InSingletonScope();
}
}
How can i create a class with zero constructor, just like MessageBox class which has no constructor.
I can not make this class static, beacause a public static method is declared in it, and that method makes object of this class.
in C# 3.5
i want to make this class just like System.Windows.Forms.MessageBox class,
in which there is no constructor and
when we create object of this class error occurres :
this class has no constructor
where as a class with a private constructor when object creates error occurrs -
the constructor is not accessible due to its protection level.
The only way to create a class without a constructor is to use static class.
However, it seem you want to be able to create instances of this class from inside the class itself, which is not possible with a static class. For that, you should give the class a private constructor:
class Foo
{
private Foo() { }
public static Foo Create()
{
return new Foo(); // Only members of Foo can directly invoke the constructor.
}
}
If a method outside of Foo in the same assembly tries to instantiate Foo, the message given will be that the constructor is not accessible due to its protection level. If you try to access it from another assembly, it will give the message that Foo has no constructors.
The methods on MessageBox are static; you can do that with the static modifier:
public static class Foo {
public static void Bar() {...}
}
then:
Foo.Bar();
In earlier versions of c# (before static was allowed on classes) you had to cheat:
public class Foo {
private Foo() {} // hide the constructor
public static void Bar() {...}
}
Make it static class with no constructor or make it an Abstract class.
Make a static class, or make a class with a private constructor.
You can add public STATIC methods into your class and you would acheve the same as in messagebox.
Remember that static methods cannot access non static properties or methods in the same class.
Hope it helps.
Consider usage of Creational patterns, described in GOF ("Gang Of Four")
There are the following ways:
1) If you want to have only one instance of object to be created, use Singleton
There is a good example of thread-safe singleton on MSDN
In this strategy, the instance is created the first time any member of
the class is referenced
public sealed class Singleton
{
private static readonly Singleton instance = new Singleton();
private Singleton(){}
public static Singleton Instance
{
get
{
return instance;
}
}
}
2) If you don't want to specify the exact class to create, use Factory method
Here is an extract from an article on C#-Corner Factory method Design pattern using C#
abstract class Factory
{
public abstract Product GetProduct(); //Factory Method Declaration
}
class concreteFactoryforProcuct1 : Factory
{
public override Product GetProduct() //Factory Method Implementation
{
return new Product1();
}
}
3) If there is a group of objects to be created this way, use Abstract factory
Here are extracts from an article on codeproject: Understanding and implementing abstract factory pattern in C#
Creating the Abstract Factory
interface IPhoneFactory //'I' stands for interface no relation with Iphone
{
ISmart GetSmart();
IDumb GetDumb();
}
Creating the Concrete Factories
class SamsungFactory : IPhoneFactory
{
public ISmart GetSmart()
{
return new GalaxyS2();
}
public IDumb GetDumb()
{
return new Primo();
}
}
...
Creating the Client
enum MANUFACTURERS
{
SAMSUNG,
HTC,
NOKIA
}
class PhoneTypeChecker
{
IPhoneFactory factory;
...
public PhoneTypeChecker(MANUFACTURERS m)
{
m_manufacturer= m;
}
public void CheckProducts()
{
switch (m_manufacturer)
{
case MANUFACTURERS.SAMSUNG:
factory = new SamsungFactory();
break;
case MANUFACTURERS.HTC:
factory = new HTCFactory();
break;
case MANUFACTURERS.NOKIA:
factory = new NokiaFactory();
break;
}
...
factory.GetSmart();
factory.GetDumb();
...
}
}
static void Main(string[] args)
{
PhoneTypeChecker checker = new PhoneTypeChecker(MANUFACTURERS.SAMSUNG);
checker.CheckProducts();
...
}
4) Use you common sense to develop your own design that would satisfy your needs.
If the purpose of it is not allowing user it instantiate new instances of the class you could make
all constructors less visible then public .
For example - protected.
I have an interface based class that I want to have a few static classes as properties. However, I can't seem to find a way to use a static class as an instance property on a class based on an interface.
public interface IHttpHelp
{
ItemsManager {get;set;}
}
public static class ItemsManager
{
//static methods
}
public class HttpHelper
{
public ItemsManager { get { return ItemsManager;}
}
The above code won't work because of the "ItemsManager is used like a variable but it's a type error." Is there anyway to use a class this way?
For some insight into what I'm doing - I have a few static helper classes that access the httpruntime and current context. I currently use them directly, but wanted to move into a container class that will be used IoC. I could make them instance classes and forget about it, but I'm wondering f there's a way to this.
You can't use a static class like that, because by definition you can't create an instance of it, so you can't return it from a property. Make it a singleton instead:
public class ItemsManager
{
#region Singleton implementation
// Make constructor private to avoid instantiation from the outside
private ItemsManager()
{
}
// Create unique instance
private static readonly ItemsManager _instance = new ItemsManager();
// Expose unique instance
public static ItemsManager Instance
{
get { return _instance; }
}
#endregion
// instance methods
// ...
}
public class HttpHelper
{
public ItemsManager ItemsManager { get { return ItemsManager.Instance; } }
}
This is not supported by the language directly. You can either write a proxy class manually or use a library like the Duck Typing Project to emit a proxy class at runtime.
Both will have the same result: you will have a class that implements the interface, and proxies all calls to the static methods of the static class. Whether you want to write this yourself or use the duck typing library is up to you.
EDIT: Thomas' answer of using a singleton would be the way to go, if you have that option.
Static classes can't implement interfaces--it really wouldn't make much sense. An interface provides a standard API that all instances will support and you can swap instances and polymorphically access the methods through the standard interface. With a static class, all references to it are through the class anyways.
Typically in this situation you want a factory to support DI of an instance class that implements your helper.
public interface IHttpHelper
{ }
public class RealHttpHelper
{ ... }
public class FakeHttpHelper
{ ... }
public static class HttpHelper
{
public static IHttpHelper Instance
{
get
{
return whatever ? new RealHttpHelper() : new FakeHttpHelper();
}
}
}
...
HttpHelper.Instance.Context...
...
I ran into a problem today and a friend recommended I use a global static instance or more elegantly a singleton pattern. I spent a few hours reading about singletons but a few things still escape me.
Background:
What Im trying to accomplish is creating an instance of an API and use this one instance in all my classes (as opposed to making a new connection, etc).
There seems to be about 100 ways of creating a singleton but with some help from yoda I found some thread safe examples. ..so given the following code:
public sealed class Singleton
{
public static Singleton Instance { get; private set; }
private Singleton()
{
APIClass api = new APIClass(); //Can this be done?
}
static Singleton() { Instance = new Singleton(); }
}
How/Where would you instantiate the this new class and how should it be called from a separate class?
EDIT:
I realize the Singleton class can be called with something like
Singleton obj1 = Singleton.Instance();
but would I be able to access the methods within the APIs Class (ie. obj1.Start)? (not that I need to, just asking)
EDIT #2: I might have been a bit premature in checking the answer but I do have one small thing that is still causing me problems. The API is launching just fine, unfortunately Im able to launch two instances?
New Code
public sealed class SingletonAPI
{
public static SingletonAPI Instance { get; private set; }
private SingletonAPI() {}
static SingletonAPI() { Instance = new SingletonAPI(); }
// API method:
public void Start() { API myAPI = new API();}
}
but if I try to do something like this...
SingletonAPI api = SingletonAPI.Instance;
api.Start();
SingletonAPI api2 = SingletonAPI.Instance; // This was just for testing.
api2.Start();
I get an error saying that I cannot start more than one instance.
Why not just add a public APIClass property to your singleton?
public sealed class Singleton
{
public static Singleton Instance { get; private set; }
private APIClass _APIClass;
private Singleton()
{
_APIClass = new APIClass();
}
public APIClass API { get { return _APIClass; } }
static Singleton() { Instance = new Singleton(); }
}
Then your calling site looks like:
Singleton.Instance.API.DoSomething();
Or if you are the author of the API class, you could make it a singleton itself, instead of wrapping it in a singleton:
public sealed class SingletonAPI
{
public static SingletonAPI Instance { get; private set; }
private SingletonAPI() {}
static SingletonAPI() { Instance = new SingletonAPI(); }
// API method:
public void DoSomething() { Console.WriteLine("hi"); }
}
API call:
SingletonAPI.Instance.DoSomething();
Here is the official Microsoft approach.
The beauty of the singleton is that you can use and access it anywhere in your code without having to create an instance of the class. In fact that is it's raison d'etre, a single instance of a class eg
Singleton.Instance.MyValue and Singleton.Instance.DoSomething();
You wouldn't instantiate the class - the pattern you're using basically instantiates itself the first time it's used. The advantage to the method you're using is that it's thread safe (will only instantiate once, no matter how many threads try to access it), lazy (it won't instantiate until you try to access the Singleton class), and simple in implementation.
All you need to do to use this is to do:
Singleton.Instance.MyMethodOnSingleton();
Or, alternatively:
Singleton myInstance = Singleton.Instance; // Will always be the same instance...
myInstance.DoSomething();