MS unity container - c#

I have an interface IInterface and it looks something like below -
public interface IInterface
{
void SomeMethod1();
void SomeMethod2();
void SomeMethod3();
.
.
.
}
One of the implementations is something like -
public class Implementation : IInterface
{
private Object obj;
public Implementation(Object obj)
{
this.obj = obj;
// Do Something
}
public void SomeMethod1()
{
lock(obj)
{
// Do Something
}
}
public void SomeMethod2()
{
// Do Something
}
public void SomeMethod3()
{
lock(obj)
{
// Do Something
}
}
.
.
.
}
How to pass a static readonly instance of type Object while registering Implementation class with type IInterface via unity configuration?

My preferred approach is probably to create a factory for creating IInterfaces
public interface IInterface
{
void SomeMethod1();
}
public interface IInterfaceFactory
{
IInterface CreateInterface();
}
public class StandardInterfaceFactory : IInterfaceFactory
{
// Define your static lock object here. Other customers
// can define their own IInterfaceFactory to use a
// different lock object.
private static readonly object lockObject = new object();
public IInterface CreateInterface()
{
return new StandardInterface(lockObject);
}
}
public class StandardInterface : IInterface
{
private readonly object lockObject;
public StandardInterface(object lockObject)
{
this.lockObject = lockObject;
}
public void SomeMethod1()
{
lock (this.lockObject)
{
Console.WriteLine("I've locked on " + lockObject);
}
}
}
Your unity configuration and client code will then look like this.
void Main()
{
IUnityContainer container = new UnityContainer();
// This mapping can be done trivially in XML configuration.
// Left as an exercise for the reader :)
container.RegisterType<IInterfaceFactory, StandardInterfaceFactory>();
IInterfaceFactory factory = container.Resolve<IInterfaceFactory>();
IInterface myInterface = factory.CreateInterface();
myInterface.SomeMethod1();
}

Related

Interface constraints in generics

Let's say, I have a list of strategies which are presented as interfaces and a class (Container) which implements these strategies explicitly. Now I want a method to perform one of these strategies as it's specified in the generic type parameter. The question is in the code.
interface IStrategy
{
void PerformAction();
}
interface IChasingStrategy : IStrategy
{
new void PerformAction();
}
interface ITestStrategy : IStrategy
{
new void PerformAction();
}
class Container : IChasingStrategy, ITestStrategy
{
void IChasingStrategy.PerformAction()
{
Console.WriteLine("ChasingStrategy");
}
void IStrategy.PerformAction()
{
Console.WriteLine("Strategy");
}
void ITestStrategy.PerformAction()
{
Console.WriteLine("TestStrategy");
}
}
class Program
{
static void PerformStrategy<TStrategy>(Container container) where TStrategy : IStrategy
{
TStrategy strategy = container; //why can't I use here implicit casting?
//However this is valid:
//IStrategy strat = container;
//IChasingStrategy ch_strat = container;
//ITestStrategy ts_strat = container;
strategy.PerformAction();
}
static void Main(string[] args)
{
var container = new Container();
PerformStrategy<IChasingStrategy>(container);
}
}
You can let it decide at runtume, which Strategy should it run by the following code.
class Container<T> Where T : IStrategy
{
public void ActionFactory()
{
T.PerformAction();
}
.
.
.
}
And in the Program class:
static void PerformStrategy<TStrategy>(Container<TStrategy> container) where TStrategy : IStrategy
{
container.ActionFactory(); //to perform the desired action for your strategy
}
When you calling the PerformStrategy method, you can decide what container should it get by:
PerformStrategy(new Container<IChasingStrategy>);
You can take off the class binding by making the ActionFactory method generic.
class Container
{
public void ActionFactory<T>() where T: IStrategy
{
T.PerformAction();
}
.
.
.
}
class Program
{
static void PerformStrategy<TStrategy>(Container container) where T: IStrategy
{
container.ActionFactory<TStrategy>(); //to perform the desired action for your strategy
}
}
PerformStrategy<IChasingStrategy>(new Container());

How to call static method of static generic class with C# Reflection?

I have many classes with these implementations:
internal static class WindowsServiceConfiguration<T, Y> where T : WindowsServiceJobContainer<Y>, new() where Y : IJob, new()
{
internal static void Create()
{
}
}
public class WindowsServiceJobContainer<T> : IWindowsService where T : IJob, new()
{
private T Job { get; } = new T();
private IJobExecutionContext ExecutionContext { get; }
public void Start()
{
}
public void Install()
{
}
public void Pause()
{
}
public void Resume()
{
}
public void Stop()
{
}
public void UnInstall()
{
}
}
public interface IWindowsService
{
void Start();
void Stop();
void Install();
void UnInstall();
void Pause();
void Resume();
}
public class SyncMarketCommisionsJob : IJob
{
public void Execute(IJobExecutionContext context)
{
}
}
public interface IJob
{
void Execute(IJobExecutionContext context);
}
I would like to call Create() method of WindowsServiceConfiguration static class by reflection as below:
WindowsServiceConfiguration<WindowsServiceJobContainer<SyncMarketCommisionsJob>, SyncMarketCommisionsJob>.Create();
and I don't know how to do that by using Activator or something like that in order to call Create method in my C# code?
best regards.
Something like this ought to work:
// Get the type info for the open type
Type openGeneric = typeof(WindowsServiceConfiguration<,>);
// Make a type for a specific value of T
Type closedGeneric = openGeneric.MakeGenericType(typeof(WindowsServiceJobContainer<SyncMarketCommisionsJob>), typeof(SyncMarketCommisionsJob));
// Find the desired method
MethodInfo method = closedGeneric.GetMethod("Create", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.InvokeMethod);
// Invoke the static method
method.Invoke(null, new object[0]);

C# Transient Dependency Pattern

I have the following situation.
SomeClass has a dependency on IDiagram and Diagram implements that interface. The lifetime of SomeClass is the lifetime of the Application, however the lifetime a Diagram is shorter. Say it could change when a certain button is pressed.
Since I could not find anything satisfying on this problem I came up with the pattern depicted in the Diagram below.
The Observer of the Diagram would be aware that the Diagram can change and set the correct instance when it changes.
The Observer would implement the IDiagram interface by delegating the methods of the current Diagram instance.
SomeFactory would create new Diagrams and RaiseChanged.
SomeClass would not be aware of any of this.
Is enforcing this pattern a good idea, which downsides are there? Is there a better solution to this problem?
Example code with IDependency instead of IDiagram below:
private static void Main(string[] args)
{
var transientDependency = new TransientDependency();
var dependencyObserver = new DependecyObserver(transientDependency);
var dependencyFactory = new Factory(transientDependency);
var someClass = new SomeClass(dependencyObserver);
var someOtherClass = new SomeClass(dependencyObserver);
// Note that someClass can only be used after the dependency has been created, because the Changed event has to be invoked
dependencyFactory.CreateDependency();
}
public class DependecyObserver : IDependency
{
public DependecyObserver(TransientDependency transient)
{
transient.Changed += (s, dependency) => Dependency = dependency;
}
private Dependency Dependency { get; set; }
public void SomeMethod()
{
Dependency.SomeMethod();
}
}
public class Factory
{
private TransientDependency TransientDependency { get; }
public Factory(TransientDependency transientDependency)
{
TransientDependency = transientDependency;
}
public void CreateDependency()
{
TransientDependency.RaiseChanged(new Dependency());
}
}
public class SomeClass
{
public SomeClass(IDependency dependency)
{
dependency.SomeMethod();
}
}
public class TransientDependency : TransientInstance<Dependency> { }
public abstract class TransientInstance<T>
{
public EventHandler<T> Changed;
public void RaiseChanged(T instance)
{
Changed?.Invoke(this, instance);
}
}
public class Dependency : IDependency
{
public void SomeMethod()
{
throw new NotImplementedException();
}
}
public interface IDependency
{
void SomeMethod();
}

implementing delegate in interface

I can't find a way to implement delegate in interface
I want to get this:
public class SomeClass : ISomeInterface
{
public delegate void SomeCallback();
public SomeCallback callback;
public void SomeMethod()
{
callback.invoke();
}
}
public class MainClass
{
void Callback() { Console.WriteLine("Callback"); }
public void Start()
{
SomeClass s = new SomeClass();
s.callback = Callback;
s.SomeMethod();
}
}
but in case when I create instance of the class "SomeClass" using interface:
public class MainClass
{
void Callback() { Console.WriteLine("Callback"); }
public void Start()
{
ISomeInterface s = new SomeClass(); // <<<----
s.callback = Callback; // here will be an error :(
s.SomeMethod();
}
}
Please, help me with it :)
Moving the callback to the interface is required if you want to use the callback without casing to a concrete type. Note that your current implementation has callback as a field. To declare it in an interface, you must make it a property.
Because properties are really methods, you must implement the property in your concrete class. Using an auto-property is fine for the implementation here.
Once you've made those changes, you can then set and call the callback using only the interface.
public delegate void SomeCallback();
public interface ISomeInterface {
SomeCallback callback { get; set; }
void SomeMethod();
}
public class SomeClass : ISomeInterface
{
public SomeCallback callback { get; set; }
public void SomeMethod()
{
callback.Invoke();
}
}
public class MainClass
{
void Callback() { Console.WriteLine("Callback"); }
public void Start()
{
ISomeInterface s = new SomeClass();
s.callback = Callback;
s.SomeMethod();
}
}

Passing dependency into Factory

We are using factory to create an instance of Subscribers. Each subscriber can have its own dependency.
Each subscriber will use constructor injection.
Should I pass dependency into subscribers through Subscriber Factory? Every time adding new dependency in any subscriber will change Subscriber factory?
public interface IMessageSubscriber
{
bool Process(string message)
}
public class MessageSubscriber1 : IMessageSubscriber
{
public bool Process(string message)
{
//Some custom logic
}
}
public class MessageSubscriber2 : IMessageSubscriber
{
public bool Process(string message)
{
//Some custom logic
}
}
public class MessageSubscriberFactory
{
//SubscriberType is enum
public IMessageSubscriber Get(SubscriberType type)
{
if(type == 1)
{
return new MessageSubscriber1();
}
else if(type == 2)
{
return new MessageSubscriber2();
}
}
}
//Main class
public class Process
{
public static void Main(string[] args)
{
MessageSubscriberFactory fac = new MessageSubscriberFactory();
foreach SubscriberType
{
string = "Message";
IMessageSubscriber subscriber = fac.Get(type);
subscriber.Process(message)
}
}
}
One approach would be to use named registrations with a DI/IOC container. This would involve using the container in a service locator fashion (which some people oppose), but I think it could make sense in this case. The example below is pretty crude, but it does give you an approach to handle subscribers with different dependencies without passing them into the factory. I used Unity here and you'd want to wrap the container reference rather than referencing directly, but this gets the point across.
public interface ILowerCaseWriter
{
void Write(string message);
}
public class LowerCaseWriter : ILowerCaseWriter
{
public void Write(string message)
{
Console.WriteLine(message.ToLower());
}
}
public interface IUpperCaseWriter
{
void Write(string message, int number);
}
public class UpperCaseWriter : IUpperCaseWriter
{
public void Write(string message, int number)
{
Console.WriteLine("{0}:{1}", number, message.ToUpper());
}
}
public interface ISubscriber
{
void Write();
}
public class Subscriber1 : ISubscriber
{
private ILowerCaseWriter _writer;
public Subscriber1(ILowerCaseWriter writer)
{
_writer = writer;
}
public void Write()
{
_writer.Write("Using subscriber 1");
}
}
public class Subscriber2 : ISubscriber
{
private IUpperCaseWriter _writer;
public Subscriber2(IUpperCaseWriter writer)
{
_writer = writer;
}
public void Write()
{
_writer.Write("Using subscriber 2", 2);
}
}
public class SubscriberFactory
{
private UnityContainer _container;
public SubscriberFactory()
{
_container = new UnityContainer();
_container.RegisterType<ILowerCaseWriter, LowerCaseWriter>();
_container.RegisterType<IUpperCaseWriter, UpperCaseWriter>();
_container.RegisterType<ISubscriber, Subscriber1>("Subscriber1");
_container.RegisterType<ISubscriber, Subscriber2>("Subscriber2");
}
public ISubscriber GetSubscriber(int type)
{
switch (type)
{
case 1:
return _container.Resolve<ISubscriber>("Subscriber1");
case 2:
return _container.Resolve<ISubscriber>("Subscriber2");
default:
throw new Exception();
}
}
}
class Program
{
private static void Main(string[] args)
{
var factory = new SubscriberFactory();
var subscriber = factory.GetSubscriber(1);
subscriber.Write();
Console.ReadLine();
}
}

Categories

Resources