release static WCF resource - c#

I have declared static resource as follows:
public DiagnosticModule : TestModule
{
private static ChannelFactory<IDiagnosticService> _diagnosticsChannelFactory;
private static ChannelFactory<IDiagnosticService> DiagnosticsChannelFactory => _diagnosticsChannelFactory ?? throw new FaultException<ApciFault>(new Fault{ FaultMessage = "Diagnostic Service Channel is NOT initialized yet" },string.Empty);
static DiagnosticModule()
{
.............
_diagnosticsChannelFactory = new ChannelFactory<IDiagnosticService>(new NetTcpBinding(SecurityMode.None),endPoint);
.............
}
public static void func1(...)
{
IDiagnosticService v5DiagnosticInformationClient = null;
try
{
v5ClearDiagnosticInformationClient = DiagnosticsChannelFactory.CreateChannel();
...................
((IClientChannel)v5ClearDiagnosticInformationClient).Close();
}
catch(Exception e)
{
((IClientChannel)v5ClearDiagnosticInformationClient).Abort();
}
}
All the functions within the DiagnosticModule class are static and I am looking for a way to call so that I can close the factory I have instantiated inside the static constructor:
DiagnosticsChannelFactory.Close();
Where to call the above snippet inside the class ?

Related

Is it possible to have a singleton exist accross different projects within a solution?

I am attempting to communicate information between two different projects. One is a remoting server and the other a WPF application. I have created a singleton class but have noticed that each time one project calls the GetInstance method it creates a new instance of the singleton. Is it possible to have a singleton accross projects as it doesn't seem it is and if that is the case, why is that?
Below is my code for the singleton
public class CommunicationSingleton
{
private int jobCount = 0;
private Job jobInProgress;
private List<Job> jobs = new List<Job>();
private static CommunicationSingleton instance = new CommunicationSingleton();
static readonly object obj = new object();
private CommunicationSingleton() { }
public static CommunicationSingleton GetInstance()
{
lock (obj)
{
if (instance == null)
{
return instance = new CommunicationSingleton();
}
else
{
return instance;
}
}
}
public void AddJob(Job job)
{
jobs.Add(job);
}
public List<Job> GetJobs()
{
return jobs;
}
public void IncreaseJobCount(int jobCount)
{
this.jobCount += jobCount;
}
public int GetJobCount()
{
return jobCount;
}
public void JobInProgress(Job jobInProgress)
{
this.jobInProgress = jobInProgress;
}
public Job GetJobInProgress()
{
return jobInProgress;
}
}

How to do .NET runtime method patch on generic class's static non-generic method? (Harmony or MonoMod)

In this example, I want to patch PatchTarget.QSingleton\<T\>.get_Instance().
How to get it done with Harmony or MonoMod?
Harmony:
"Unhandled exception. System.NotSupportedException: Specified method
is not supported."
MonoMod:
"Unhandled exception. System.ArgumentException: The given generic
instantiation was invalid."
Code snippet: (runnable with dotnetfiddle.net)
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Emit;
using HarmonyLib;
namespace PatchTarget {
public abstract class QSingleton<T> where T : QSingleton<T>, new() {
protected static T instance = null; protected QSingleton() { }
public static T Instance { get {
if (instance == null) {
instance = new T();
Console.Write($"{typeof(T).Name}.Instance: impl=QSingleton");
}
return instance;
} }
}
}
namespace Patch {
public class TypeHelper<T> where T : PatchTarget.QSingleton<T>, new() {
public static T InstanceHack() {
Console.Write($"{typeof(T).Name}.Instance: impl=InstanceHack");
return null;
}
}
public static class HarmonyPatch {
public static Harmony harmony = new Harmony("Try");
public static void init() {
var miOriginal = AccessTools.Property(typeof(PatchTarget.QSingleton<>), "Instance").GetMethod;
var miHack = AccessTools.Method(typeof(TypeHelper<>), "InstanceHack");
harmony.Patch(miOriginal, prefix: new HarmonyMethod(miHack));
}
}
public static class MonoModPatch {
public static MonoMod.RuntimeDetour.Detour sHook;
public static void init() {
var miOriginal = AccessTools.Property(typeof(PatchTarget.QSingleton<>), "Instance").GetMethod;
var miHack = AccessTools.Method(typeof(TypeHelper<>), "InstanceHack");
sHook = new MonoMod.RuntimeDetour.Detour(miOriginal, miHack);
}
}
}
class Program {
public static void Main() {
Patch.HarmonyPatch.init();
// Patch.MonoModPatch.init();
Console.WriteLine($"done");
}
}
After some trial and error, I got something working, but not the reason behind it.
Both Harmony and MonoMod.RuntimeDetour can hook with the typeof(QSingleton<SampleA>).GetMethod(), but not typeof(QSingleton<>).GetMethod().
Harmony output is unexpected.
Harmony attribute annotation doesn't seem to work.
Generating IL seems useless due to the potential lack of TypeSpec for generic.
Questions:
What is the difference between QSingleton<>.Instance and QSingleton<SampleA>.Instance in the sample?
I would guess that <>.Instance is MethodDef, while <SampleA>.Instance is TypeSpec.MemberRef.
Why does Harmony/MonoMod.RuntimeDetour need TypeSpec.MemberRef? For generating redirection stub?
Is it possible to fix the hook under Harmony?
Can Harmony/MonoMod generates "ldtoken <TypeSpec>" if TypeSpec already exists?
Can Harmony/MonoMod dynamically generates necessary TypeSpec for generics?
Code snippet: (runnable with dotnetfiddle.net)
using System;
using HarmonyLib;
namespace PatchTarget {
public abstract class QSingleton<T> where T : QSingleton<T>, new() {
protected static T instance = null; protected QSingleton() { }
public static T Instance { get {
if (instance == null) {
instance = new T();
Console.WriteLine($"{typeof(T).Name}.Instance: impl=QSingleton");
}
return instance;
} }
}
public class SampleA : QSingleton<SampleA> {
public SampleA() { Console.WriteLine("SampleA ctor"); }
}
public class SampleB : QSingleton<SampleB> {
public SampleB() { Console.WriteLine("SampleB ctor"); }
}
}
namespace Patch {
public class TypeHelper<T> where T : PatchTarget.QSingleton<T>, new() {
public static T InstanceHack() {
Console.WriteLine($"{typeof(T).Name}.Instance: impl=InstanceHack");
return null;
}
// For Harmony as Prefix, but attribute does not work.
public static bool InstanceHackPrefix(T __result) {
Console.WriteLine($"{typeof(T).Name}.Instance: impl=InstanceHack");
__result = null;
return false;
}
}
public static class HarmonyPatch {
public static Harmony harmony = new Harmony("Try");
public static void init() {
// Attribute does not work.
// Transpiler does not work because the lack of TypeSpec to setup generic parameters.
var miOriginal = AccessTools.Property(typeof(PatchTarget.QSingleton<PatchTarget.SampleB>), "Instance").GetMethod;
var miHack = AccessTools.Method(typeof(TypeHelper<PatchTarget.SampleB>), "InstanceHackPrefix");
harmony.Patch(miOriginal, prefix: new HarmonyMethod(miHack));
}
}
public static class MonoModPatch {
public static MonoMod.RuntimeDetour.Detour sHook;
public static void init() {
var miOriginal = AccessTools.Property(typeof(PatchTarget.QSingleton<PatchTarget.SampleB>), "Instance").GetMethod;
var miHack = AccessTools.Method(typeof(TypeHelper<PatchTarget.SampleB>), "InstanceHack");
sHook = new MonoMod.RuntimeDetour.Detour(miOriginal, miHack);
}
}
}
class Program {
public static void Main() {
_ = PatchTarget.SampleA.Instance;
// MonoMod works (replaces globally).
// Harmony hooks, but in an expected way (T becomes SampleB, not 1st generic type parameter).
// try { Patch.HarmonyPatch.init(); } catch (Exception e) { Console.WriteLine($"Harmony error: {e.ToString()}"); }
try { Patch.MonoModPatch.init(); } catch (Exception e) { Console.WriteLine($"MonoMod error: {e.ToString()}"); }
_ = PatchTarget.SampleB.Instance;
_ = PatchTarget.SampleA.Instance;
Console.WriteLine($"done");
}
}
MonoMod.RuntimeDetour Output:(Work as intended)
SampleA.Instance: impl=QSingleton
SampleB.Instance: impl=InstanceHack
SampleA.Instance: impl=InstanceHack
Harmony Output:(Broken <T>)
SampleA.Instance: impl=QSingleton
SampleB.Instance: impl=InstanceHack
SampleB.Instance: impl=InstanceHack

Why is FieldInfo.GetValue(null) not working in static constructor

See the code below. I want a class that automatically enumerates all the defined static readonly instances of its own type (see TestClass as an example, it defines 3 static readonly instances of its own type).
I want this automation because I want to loop over the defined types and not risk the change of forgetting to add a new instance to the list of All.
Ok, I have it working, that is not the point. But why doesn't FillAll work when called from a static constructor? See the commented static constructor in DefinedInstancesBase<T> code. I mean FieldInfo.GetValue(null) returns null in the static constructor, though the debugger has already hit creating the static readonly instances before the FieldInfo.GetValue(null) is called.
I'm very curious why it doesn't work. Is this by design?
public abstract class DefinedInstancesBase<T>
{
public static IList<T> All
{
get
{
if (_All == null)
{
FillAll();
}
return _All;
}
}
//Why this doesn't work? No idea.
//static DefinedInstancesBase()
//{
// FillAll();
//}
private static void FillAll()
{
var typeOfT = typeof(T);
var fields = typeOfT.GetFields(BindingFlags.Public | BindingFlags.Static);
var fieldsOfTypeT = fields.Where(f => f.FieldType == typeOfT);
_All = new List<T>();
foreach (var fieldOfTypeT in fieldsOfTypeT)
{
_All.Add((T)fieldOfTypeT.GetValue(null));
}
}
private static List<T> _All = null;
}
[TestClass]
public class DefinedInstancesTest
{
[TestMethod]
public void StaticReadOnlyInstancesAreEnumerated()
{
//Given
var expectedClasses = new List<TestClass>
{
TestClass.First,
TestClass.Second,
TestClass.Third,
};
//When
var actualClasses = TestClass.All;
//Then
for (var i=0; i<expectedClasses.Count; i++)
{
Assert.AreEqual(expectedClasses[i].Id, actualClasses[i].Id);
}
}
private class TestClass : DefinedInstancesBase<TestClass>
{
public static readonly TestClass First = new TestClass(1);
public static readonly TestClass Second = new TestClass(2);
public static readonly TestClass Third = new TestClass(3);
public int Id { get; private set; }
private TestClass(int pId)
{
Id = pId;
}
}
}
There are two separate issues at work here.
There is a typo in your static constructor in the code above. Try changing static DefinedInstances() to static DefinedInstancesBase(), because currently it is just specified as a private static function.
The second and more important issue is to understand the order that the various constructors are being called in. What is happening is that the static constructor on the base abstract class is getting triggered by the instantiation (during member initializer) of the First field in the derived class. Therefore, First is still null when the static constructor of DefinedInstancesBase class is being called (and thus the FindAll() method).
See the following code (slightly modified to better illustrate the issue) and output:
public void Main()
{
DefinedInstancesTest dit = new DefinedInstancesTest();
dit.StaticReadOnlyInstancesAreEnumerated();
}
public abstract class DefinedInstancesBase<T>
{
public static IList<T> All
{
get
{
//if (_All == null)
// FillAll();
return _All;
}
}
// correctly named static ctor
static DefinedInstancesBase() { FillAll(); }
private static void FillAll()
{
Console.WriteLine("FillAll() called...");
var typeOfT = typeof(T);
var fields = typeOfT.GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static);
var fieldsOfTypeT = fields.Where(f => f.FieldType == typeOfT);
_All = new List<T>();
foreach (var fieldOfTypeT in fieldsOfTypeT)
{
_All.Add((T)fieldOfTypeT.GetValue(null));
}
}
private static List<T> _All = null;
}
//[TestClass]
public class DefinedInstancesTest
{
//[TestMethod]
public void StaticReadOnlyInstancesAreEnumerated()
{
//Given
var expectedClasses = new List<TestClass>
{
TestClass.First,
TestClass.Second,
TestClass.Third,
};
//When
var actualClasses = TestClass.All;
//Then
for (var i=0; i<expectedClasses.Count; i++)
{
//Assert.AreEqual(expectedClasses[i].Id, actualClasses[i].Id);
if (expectedClasses[i].Id != actualClasses[i].Id)
Console.WriteLine("not equal!");
}
}
private class TestClass : DefinedInstancesBase<TestClass>
{
public static readonly TestClass First;
public static readonly TestClass Second;
public static readonly TestClass Third;
public int Id { get; private set; }
static TestClass()
{
Console.WriteLine("TestClass() static ctor called...");
First = new TestClass(1);
Second = new TestClass(2);
Third = new TestClass(3);
}
private TestClass(int pId)
{
Console.WriteLine("TestClass({0}) instance ctor called...", pId);
Id = pId;
}
}
}
TestClass() static ctor called...
// the line "First = new TestClass(1);" now triggers the base class static ctor to be called,
// but the fields First, Second, and Third are all still equal to null at this point!
FillAll() called...
TestClass(1) instance ctor called...
TestClass(2) instance ctor called...
TestClass(3) instance ctor called...
// this null reference exception to be expected because the field value actually was null when FindAll() added it to the list
Unhandled Expecption:
System.NullReferenceException: Object reference not set to an instance of an object.

C# How to treat static class as a variable

I have a static Class and within it I have multiple public static attributes. I treat this class as my global class.
However now I need to treat this class as a variable so that I can pass it to a method of another class for processing..
I can't instantiate this class.. So in effect I can only assign the variables inside this class.
Is my understanding correct or am I missing something?
public static class Global
{
public const int RobotMax = 2;
// GUI sync context
public static MainForm mainForm;
public static SynchronizationContext UIContext;
// Database
public static Database DB = null;
public static string localDBName = "local.db";
public static Database localDB = null;
public static Database ChangeLogDB = null;
public static string changeLogDBName = "ChangeLog.db";
}
Let say I have a class like this, and I need to somehow keep a copy of this in another class maybe
public static class Global_bk
{
public const int RobotMax = 2;
// GUI sync context
public static MainForm mainForm;
public static SynchronizationContext UIContext;
// Database
public static Database DB = null;
public static string localDBName = "local.db";
public static Database localDB = null;
public static Database ChangeLogDB = null;
public static string changeLogDBName = "ChangeLog.db";
}
I need to copy the contents from Global to Global_bk.
And after that I need to compare the contents of the two classes in a method like
static class extentions
{
public static List<Variance> DetailedCompare<T>(T val1, T val2)
{
List<Variance> variances = new List<Variance>();
FieldInfo[] fi = val1.GetType().GetFields();
foreach (FieldInfo f in fi)
{
Variance v = new Variance();
v.Prop = f.Name;
v.valA = f.GetValue(val1);
v.valB = f.GetValue(val2);
if (!v.valA.Equals(v.valB))
variances.Add(v);
}
return variances;
}
}
class Variance
{
string _prop;
public string Prop
{
get { return _prop; }
set { _prop = value; }
}
object _valA;
public object valA
{
get { return _valA; }
set { _valA = value; }
}
object _valB;
public object valB
{
get { return _valB; }
set { _valB = value; }
}
}
So on my main form, how do I go about calling the compare method and passing the static Global class inside?
example: extentions.DetailedCompare(Global, Global_bk) ? Of course this would give me an error because I cant pass a type as a variable.
Please help me, this is driving me nuts...
How about the singleton pattern ? You can pass reference to shared interface (IDoable in exable below) and still have just one instance.
I.E.:
public interface IDoable {
int Value { get; set; }
void Foo();
}
public static class DoableWrapper {
private MyDoable : IDoable {
public int Value { get;set; }
public void Foo() {
}
}
private static IDoable s_Doable = new MyDoable();
public static IDoable Instance {
get { return s_Doable; }
}
}
Singleton is the way to go here. You can do it like this:
internal class SomeClass
{
private static SomeClass singleton;
private SomeClass(){} //yes: private constructor
public static SomeClass GetInstance()
{
return singleton ?? new SomeClass();
}
public int SomeProperty {get;set;}
public void SomeMethod()
{
//do something
}
}
The GetInstance Method will return you a SomeClass object that you can edit and pass into whatever you need.
You can access the members with classname.membername.
internal static class SomeClass
{
public static int SomeProperty {get;set;}
public static void SomeMethod()
{
//do something
}
}
static void main()
{
SomeClass.SomeProperty = 15;
SomeClass.SomeMethod();
}
The only way you are going to obtain a variable with the "class" information is using reflection. You can get a Type object for the class.
namespace Foo {
public class Bar
{
}
}
Type type = Type.GetType("Foo.Bar");
Otherwise, if you are really describing a class "instance" then use an object and simply instantiate one.
C# offers no other notation for class variables.

Getting Ninject to work

Clearly, I am missing something. I have an MVC application and have installed Ninject 3 and the MVC3 extensions (although I am running MVC4). I have a SiteSettings class that is referenced throughout the project, which looks like this:
public class SiteSettings
{
private static readonly Common.Logging.ILog Logger = Common.Logging.LogManager.GetCurrentClassLogger();
private static ObservableDictionary<string, string> settings;
private static bool Initialized = false;
private static DataPersister persister;
public static void Initialize()
{
if (Initialized) throw new InvalidOperationException("The SiteSettings object has already been initialized.");
persister = new DataPersister();
using (var u = persister.UnitOfWorkFactory.GetUnitOfWork())
{
var settingsList = u.SiteSettings.GetAll();
settings = new ObservableDictionary<string, string>(settingsList.ToDictionary(key => key.SiteSettingName, value => value.SiteSettingValue));
settings.OnChange += new kvpChangeEvent<string, string>(settings_OnChange);
}
Initialized = true;
}
static void settings_OnChange(object sender, odKVPChangeEventArgs<string, string> e)
{
using (var u = persister.UnitOfWorkFactory.GetUnitOfWork())
{
var setting = u.SiteSettings.GetByName(e.Key);
setting.SiteSettingValue = e.Value;
u.SiteSettings.Update(setting);
u.Save();
Logger.Info(i => i("Changed the '{0}' site setting from '{1}' to '{2}'.", e.Key, e.OldValue, e.Value));
}
}
private static int _ItemsPerPage;
public static int ItemsPerPage
{
get
{
return _ItemsPerPage;
}
set
{
_ItemsPerPage = value;
settings["itemsPerPage"] = value.ToString();
}
}
private static int _SessionLifeInMinutes;
public static int SessionLifeInMinutes
{
get
{
return _SessionLifeInMinutes;
}
set
{
_SessionLifeInMinutes = value;
settings["sessionLifeInMinutes"] = value.ToString();
}
}
private static string _DateFormat;
public static string DateFormat
{
get
{
return _DateFormat;
}
set
{
_DateFormat = value;
settings["defaultDateFormat"] = value;
}
}
}
I built a data persistence object like so:
public class DataPersister
{
public IUnitOfWorkFactory UnitOfWorkFactory { get; set; }
}
... and I have my NinjectWebCommon.cs looks like this:
public static class NinjectWebCommon
{
private static readonly Bootstrapper bootstrapper = new Bootstrapper();
/// <summary>
/// Starts the application
/// </summary>
public static void Start()
{
DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
bootstrapper.Initialize(CreateKernel);
}
/// <summary>
/// Stops the application.
/// </summary>
public static void Stop()
{
bootstrapper.ShutDown();
}
/// <summary>
/// Creates the kernel that will manage your application.
/// </summary>
/// <returns>The created kernel.</returns>
private static IKernel CreateKernel()
{
var kernel = new StandardKernel();
kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
RegisterServices(kernel);
return kernel;
}
/// <summary>
/// Load your modules or register your services here!
/// </summary>
/// <param name="kernel">The kernel.</param>
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IUnitOfWork>().To<NHUnitOfWork>();
kernel.Bind<IUnitOfWorkFactory>().To<NHUnitOfWorkFactory>();
}
}
It seems to me I've met all my requirements for dependency injection. My Global.asax.cs Application_Start() looks like this:
protected void Application_Start()
{
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new MonoRazorViewEngine());
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
ControllerBuilder.Current.DefaultNamespaces.Add("MyApplication.Application.Controllers");
Initialize.Security();
SiteSettings.Initialize();
}
...and yet, my SiteSettings class always has a null IUnitOfWorkFactory when I try to collect the data I need.
What am I doing wrong? Everything seems to be as all the examples suggest it should be, but I get no love.
UPDATE
Using Bassam Mehanni's advice, I rewrote my DataPersister class to look like this:
public class DataPersister
{
private IUnitOfWorkFactory UnitOfWorkFactory;
public DataPersister(IUnitOfWorkFactory unitOfWorkFactory)
{
UnitOfWorkFactory = unitOfWorkFactory;
}
public IUnitOfWork GetUnitOfWork()
{
return UnitOfWorkFactory.GetUnitOfWork();
}
}
...but of course now my SiteSettings class complains about my parameterless constructor. What should I do about that?
UPDATE 2
Ok, continuing on, I rewrote my DataPersister class like so:
public class DataPersister
{
private static readonly Common.Logging.ILog Logger = Common.Logging.LogManager.GetCurrentClassLogger();
private IUnitOfWorkFactory UnitOfWorkFactory { get; set; }
public IUnitOfWork GetUnitOfWork()
{
return UnitOfWorkFactory.GetUnitOfWork();
}
[Inject]
public DataPersister(IUnitOfWorkFactory factory)
{
Logger.Info("Injected constructor called");
UnitOfWorkFactory = factory;
}
public DataPersister()
{
Logger.Info("Parameterless constructor called");
}
}
then I rewrote my SiteSettings class like so:
public class SiteSettings
{
private static readonly Common.Logging.ILog Logger = Common.Logging.LogManager.GetCurrentClassLogger();
private ObservableDictionary<string, string> settings;
private DataPersister persister;
private SiteSettings()
{
persister = new DataPersister();
using (var u = persister.GetUnitOfWork())
{
var settingsList = u.SiteSettings.GetAll();
settings = new ObservableDictionary<string, string>(settingsList.ToDictionary(key => key.SiteSettingName, value => value.SiteSettingValue));
settings.OnChange += new kvpChangeEvent<string, string>(settings_OnChange);
}
}
private static SiteSettings instance;
public static SiteSettings Instance
{
get
{
if (instance == null)
{
instance = new SiteSettings();
}
return instance;
}
}
private void settings_OnChange(object sender, odKVPChangeEventArgs<string, string> e)
{
using (var u = persister.GetUnitOfWork())
{
var setting = u.SiteSettings.GetByName(e.Key);
setting.SiteSettingValue = e.Value;
u.SiteSettings.Update(setting);
u.Save();
Logger.Info(i => i("Changed the '{0}' site setting from '{1}' to '{2}'.", e.Key, e.OldValue, e.Value));
}
}
private int _ItemsPerPage;
public int ItemsPerPage
{
get
{
return _ItemsPerPage;
}
set
{
_ItemsPerPage = value;
settings["itemsPerPage"] = value.ToString();
}
}
private int _SessionLifeInMinutes;
public int SessionLifeInMinutes
{
get
{
return _SessionLifeInMinutes;
}
set
{
_SessionLifeInMinutes = value;
settings["sessionLifeInMinutes"] = value.ToString();
}
}
private string _DateFormat;
public string DateFormat
{
get
{
return _DateFormat;
}
set
{
_DateFormat = value;
settings["defaultDateFormat"] = value;
}
}
}
Shouldn't this work? because it doesn't. The DataPersister class always gets called with the parameterless constructor. My kernel binding looks like this:
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IUnitOfWork>().To<NHUnitOfWork>();
kernel.Bind<IUnitOfWorkFactory>().To<NHUnitOfWorkFactory>();
}
Is there something else I am missing? This is getting very frustrating.
Static classes that depencend on none static classes is something you shouldn't do when using an IoC container. Instead you should create a none static class with a singleton lifetime.
Make your SiteSettings class none static.
Inject all dependencies e.g. IUnitOfWorkFactory into SiteSettings using constructor injection
Create a binding in singleton scope for SiteSettings
Get an instance of SiteSettings wherever you need access unsing constructor injection.
Example:
public class SiteSettings {
public SiteSettings(IUnitOfWorkFactory uowFactory) { .... }
....
}
public class INeedToAccessSiteSettings
{
public INeedToAccessSiteSettings(SiteSettings siteSettings) { .... }
}
kenrel.Bind<SiteSettings>().ToSelf().InSingletonScope();
Typically ninject will inject your service in a constructor or something, it doesn't magically turn all your interfaces to object instances at run time
e.g.:
public class MyController : Controller
{
private IServiceThatINeed _serviceThatINeed;
public MyController(IServiceThatINeed serviceThatINeed)
{
_serviceThatINeed = _serviceThatINeed;
}
}
in this case since you registered your kernel instance, mvc knows how to resolve this dependence and will pass an instance of an object that implement IServiceThatINeed (assuming that you told ninject how to resolve this dependency.
Now there might be instance where you will need to get a service without it being injected in a constructor by the mvc framework, in these instances (like the one you have here), you will need to use ServiceLocator
e.g.:
var myService = ServiceLocator.Current.GetInstance<IServiceThatINeed>()
to use the ServiceLocator, you need to add a reference to Microsoft.Practices.ServiceLocation
Hope that helps!

Categories