C# only one instance of program - open few files - c#

I did everything from Example: What is the correct way to create a single-instance application? by Matt Davis.
However, I have an application to open files. I have this code:
static Mutex mutex = new Mutex(true, "{MyApplicationTest}");
[STAThread]
static void Main(string[] args)
{
if (mutex.WaitOne(TimeSpan.Zero, true))
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(args.Length == 0 ? new Form1(string.Empty) : new Form1(args[0]));
mutex.ReleaseMutex();
}
else
{
NativeMethods.PostMessage(
(IntPtr)NativeMethods.HWND_BROADCAST,
NativeMethods.WM_SHOWME,
IntPtr.Zero,
IntPtr.Zero);
}
How does open the next file in the case when the program is already running. The first file automatically opens. In contrast, the next click will only appearance of the application window on top of the screen.

Problem solved, thanks xxbbcc http://www.hanselman.com/blog/TheWeeklySourceCode31SingleInstanceWinFormsAndMicrosoftVisualBasicdll.aspx
using System;
using System.Windows.Forms;
using Microsoft.VisualBasic.ApplicationServices;
namespace SuperSingleInstance
{
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
string[] args = Environment.GetCommandLineArgs();
SingleInstanceController controller = new SingleInstanceController();
controller.Run(args);
}
}
public class SingleInstanceController : WindowsFormsApplicationBase
{
public SingleInstanceController()
{
IsSingleInstance = true;
StartupNextInstance += this_StartupNextInstance;
}
void this_StartupNextInstance(object sender, StartupNextInstanceEventArgs e)
{
Form1 form = MainForm as Form1; //My derived form type
form.LoadFile(e.CommandLine[1]);
}
protected override void OnCreateMainForm()
{
MainForm = new Form1();
}
}
}

Here is a Utility Class That I wrote a while back for a similar purpose.
(I guess the name GlobalMutexHelper is kind of redundant in this case, the name kind of stuck :)..anyways)
Since it implements IDisposable you can use it like so
using(var Mutexhelper=new GlobalMutexHelper("reasonably unique Name"))
{
//Code goes here
}
Its not necessary that this be implemented as an IDisposable but in my case I need it to be handy
as sometimes the "Single Instanceness" had to be dependent on other factors.
internal class GlobalMutexHelper : IDisposable
{
#region Constants and Fields
/// <summary>
/// The access rule.
/// </summary>
private readonly MutexAccessRule accessRule =
new MutexAccessRule(
new SecurityIdentifier(WellKnownSidType.WorldSid, null),
MutexRights.FullControl,
AccessControlType.Allow);
/// <summary>
/// The obj.
/// </summary>
private readonly Mutex obj;
/// <summary>
/// The sec settings.
/// </summary>
private readonly MutexSecurity secSettings = new MutexSecurity();
#endregion
#region Constructors and Destructors
/// <summary>
/// Initializes a new instance of the <see cref="GlobalMutexHelper"/> class.
/// </summary>
/// <param name="mutexname">
/// The mutexname.
/// </param>
/// <exception cref="TimeoutException">
/// </exception>
/// <exception cref="Exception">
/// </exception>
public GlobalMutexHelper(string mutexname)
{
if (mutexname.Trim() != string.Empty)
{
this.secSettings.AddAccessRule(this.accessRule);
bool isNew;
this.obj = new Mutex(true, "Global\\SomeUniqueName_" + mutexname, out isNew);
this.obj.SetAccessControl(this.secSettings);
if (!isNew)
{
if (this.obj.WaitOne())
{
Console.WriteLine("Signalled");
}
else
{
throw new TimeoutException("Timedout while waiting for Mutex");
}
}
}
else
{
throw new Exception("The mutex name cannot be empty");
}
}
#endregion
#region Public Methods and Operators
/// <summary>
/// The dispose.
/// </summary>
public void Dispose()
{
this.obj.ReleaseMutex();
this.obj.Dispose();
}
#endregion
}

Related

Hooking Unity Interception to a method with no parameters

I am working on a proof of concept for using Unity and I am having issues with my interceptor being called. I am using policy injection.
so here is some code
setting up unity:
private void ApplyCrossCuttingConcerns(UnityContainer container)
{
container.AddNewExtension<Interception>();
container.RegisterType<IContact, Contact>(
new InterceptionBehavior<PolicyInjectionBehavior>(),
new Interceptor<InterfaceInterceptor>());
container.Configure<Interception>()
.AddPolicy("extensionPolicy")
.AddMatchingRule<TypeMatchingRule>(new InjectionConstructor(typeof(Contact).ToString()))
.AddMatchingRule<MethodSignatureMatchingRule>(new InjectionConstructor("Save",new [] {""},true))
.AddCallHandler<ExtensionHandler>(new ContainerControlledLifetimeManager(), new InjectionConstructor());
}
my contact class that inherites from BussinessObject where the method in question lives
public class Contact : BussinessObject, IContact
{...}
public abstract class BussinessObject
{
#region Local Vars
protected readonly IRepository _repository;
protected bool isNew;
#endregion Local Vars
#region Properties
/// <summary>
/// Gets or sets a value indicating whether this instance is new.
/// </summary>
/// <value>
/// <see langword="true" /> if this instance is new; otherwise, <see langword="false" />.
/// </value>
internal bool IsNew { get { return (isNew); } set { isNew = value; } }
#endregion
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="BussinessObject"/> class.
/// </summary>
/// <param name="repository">The repository.</param>
public BussinessObject(IRepository repository)
{
if (repository.IsEmpty())
{
throw new Exception("The repository is a maditory parameter for a bussiness object");
}
_repository = repository;
}
#endregion Constructors
#region Methods
#region public
/// <summary>
/// Saves this instance.
/// </summary>
public virtual void Save()
{
Validate();
SetIdenity();
if (isNew)
{
Insert();
}
else
{
Update();
}
isNew = false;
}
/// <summary>
/// Permantlies the remove from system.
/// </summary>
/// <param name="ID">The identifier.</param>
public abstract void PermantlyRemoveFromSystem(Guid id);
#endregion public
#region Internal
/// <summary>
/// Sets the idenity.
/// </summary>
internal abstract void SetIdenity();
#endregion Internal
#region protected
/// <summary>
/// Commons the initialize.
/// </summary>
protected virtual void CommonInit()
{
isNew = false;
}
/// <summary>
/// Inserts this instance.
/// </summary>
protected abstract void Insert();
/// <summary>
/// Updates this instance.
/// </summary>
protected abstract void Update();
/// <summary>
/// Validates this instance.
/// </summary>
protected abstract void Validate();
#endregion protected
#endregion
}
Now the IContact
public interface IContact : DTO.IContact
{
void Save();
void Delete();
#region Phone Number Manipulation
bool SetDefaultNumber(PhoneNumber phNum);
PhoneNumber GetDefaultNumber();
bool HasDefaultNumber();
PhoneNumber[] GetPhoneNumbers();
PhoneNumber[] GetPhoneNumbers(bool includeDeleted);
void AddPhoneNumber(PhoneNumber phToAdd);
bool RemovePhoneNumber(PhoneNumber phToRemove);
#endregion
#region Email Address Manipulation
bool SetDefaultEMailAddress(EmailAddress emAdd);
bool HasDefaultEmailAddress();
EmailAddress[] GetAllEmailAddresses();
EmailAddress[] GetAllEmailAddresses(bool includeDeleted);
EmailAddress AddEmailAddress(string addressToAdd);
EmailAddress GetDefaultEMailAddress();
#endregion
#region Snailmail Address Manipulation
bool SetDefaultAddress(SnailMailAddress ad);
SnailMailAddress GetDefaultAddress();
bool HasDefaultAddress();
SnailMailAddress[] GetAllAddresses();
SnailMailAddress[] GetAllAddresses(bool includeDeleted);
void AddAddress(SnailMailAddress adToAdd);
bool RemoveAddress(SnailMailAddress adToRemove);
#endregion
}
and finally the extensionHandler
public class ExtensionHandler : ICallHandler
{
public int Order { get; set; }
public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
{
//going to do our work before we pass on to the next item in the pipeline
SomeFunctionality handlerFunctionality = new SomeFunctionality();
handlerFunctionality.PreformWork();
//pass on to the next item in the pipeline
var result = getNext().Invoke(input, getNext);
//we can put post processing logic in here
return result;
}
I setup a test to resolve the contact object and then set so data on it and called the save method. I have a break point at the top of the invoke method in the ExtensionHandler but I never get there. I think the issue with the way I configuring the MethodSignatureMatchingRule but I have not yet to find documentation on the net showing an example of interception being configured to a method with no parameters.
Any help would be appreaiated
so after some more experimentation I found the answer
This issue was in the matching rules
both rules where incorrect the correct code is as follows:
private void ApplyCrossCuttingConcerns(UnityContainer container)
{
container.AddNewExtension<Interception>();
container.RegisterType<IContact, Contact>(
new InterceptionBehavior<PolicyInjectionBehavior>(),
new Interceptor<InterfaceInterceptor>());
container.Configure<Interception>()
.AddPolicy("extensionPolicy")
.AddMatchingRule<TypeMatchingRule>(new InjectionConstructor(new InjectionParameter(typeof(IContact))))
.AddMatchingRule<MemberNameMatchingRule>(new InjectionConstructor(new InjectionParameter("Save")))
.AddCallHandler<ExtensionHandler>(new ContainerControlledLifetimeManager(), new InjectionConstructor());
}

Console and form in one and data transfer?

There is a code represents Console Application where I've done new Thread for the form and displaying a CustomForm on our new thread, I've also tried some kind of data transfer but I haven't successed.
Program.cs code ...
class Program {
public static CustomForm _customForm {
get {
return customForm;
}
set {
customForm = value;
customForm.Show();
}
}
private static CustomForm customForm;
/// <summary>
/// Static method which constains all the magic for the console!
/// </summary>
/// <param name="args"></param>
static void Main(string[] args) {
// Declaring Thread for the FormThread.
Thread formThread = new Thread(new ThreadStart(FormThread));
// Fires out the work of the thread.
formThread.Start();
Console.ReadKey();
// And console is still running?
// Thread formThread is still running too, thats the reason bruh!
}
/// <summary>
/// Static method which constains all the magic for the form!
/// </summary>
static void FormThread() {
customForm.lbl.Text = "Yolo, it wurks!";
Application.Run(new CustomForm());
}
}
CustomForm.cs code ...
public partial class CustomForm : Form {
public string lblText {
get {
return lbl.Text;
}
set {
lbl.Text = value;
}
}
/// <summary>
/// Just initializer, something what we'll never understand.
/// </summary>
public CustomForm() {
InitializeComponent();
}
/// <summary>
/// When the form is loaded.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void OnLoad(object sender, EventArgs e) {
Program._customForm = this;
}
}
The only thing I want to do is call the lbl's text property and set some value in a program.cs, not in the customform.cs
Sometimes form wont to show or the lbl in the form isn't changed.
customForm.lbl.Text = "Yolo, it wurks!"; executes before you are creating CustomForm.
Probably, you need to create your form in the main and pass it into Application.Run(CustomForm);
static void Main(string[] args) {
// Declaring Thread for the FormThread.
Thread formThread = new Thread(new ThreadStart(FormThread));
// Fires out the work of the thread.
customForm = new CustomForm();
formThread.Start();
Console.ReadKey();
// And console is still running?
// Thread formThread is still running too, thats the reason bruh!
}
Also, you can't change a control property from other threads. In order to change property from other thread use Invoke method.
public partial class CustomForm : Form {
public string lblText
{
get
{
return lbl.Text;
}
set
{
if (lbl.InvokeRequired)
lbl.Invoke((MethodInvoker) (() => lbl.Text = value));
else
lbl.Text = value;
}
}
}

Restarting an app as administrator that uses mutex

I have an application that uses a mutex to stop multiple instances running at the same time, and to accept command line inputs in to the running instance.
I have a function in the app that asks the user if they want to restart as admin when required. For example the features they have enabled might require admin rights.
The mutex class looks like this:
namespace SingleInstanceClassLibrary
{
/// <summary>
/// Enforces single instance for an application.
/// </summary>
public class SingleInstance : IDisposable
{
private Mutex mutex = null;
private Boolean ownsMutex = false;
private Guid identifier = Guid.Empty;
/// <summary>
/// Enforces single instance for an application.
/// </summary>
/// <param name="identifier">An identifier unique to this application. </param>
public SingleInstance(Guid identifier)
{
this.identifier = identifier;
mutex = new Mutex(true, identifier.ToString(), out ownsMutex);
}
/// <summary>
/// Indicates whether this is the first instance of this application.
/// </summary>
public Boolean IsFirstInstance
{ get { return ownsMutex; } }
/// <summary>
/// Passes the given arguments to the first running instance of the application.
/// </summary>
/// <param name="arguments">The arguments to pass.</param>
/// <returns>Return true if the operation succeded, false otherwise. </returns>
public Boolean PassArgumentsToFirstInstance(String[] arguments)
{
if (IsFirstInstance)
throw new InvalidOperationException("This is the first instance.");
try
{
using (NamedPipeClientStream client = new NamedPipeClientStream(identifier.ToString()))
using (StreamWriter writer = new StreamWriter(client))
{
client.Connect(200);
foreach (String argument in arguments)
writer.WriteLine(argument);
}
return true;
}
catch (TimeoutException)
{ } //Couldn't connect to server
catch (IOException)
{ } //Pipe was broken
return false;
}
/// <summary>
/// Listens for arguments being passed from successive instances of the applicaiton.
/// </summary>
public void ListenForArgumentsFromSuccessiveInstances()
{
if (!IsFirstInstance)
throw new InvalidOperationException("This is not the first instance.");
ThreadPool.QueueUserWorkItem(new WaitCallback(ListenForArguments));
}
/// <summary>
/// Listens for arguments on a named pipe.
/// </summary>
/// <param name="state">State object required by WaitCallback delegate.</param>
private void ListenForArguments(Object state)
{
try
{
using (NamedPipeServerStream server = new NamedPipeServerStream(identifier.ToString()))
using (StreamReader reader = new StreamReader(server))
{
server.WaitForConnection();
List<String> arguments = new List<String>();
while (server.IsConnected)
arguments.Add(reader.ReadLine());
ThreadPool.QueueUserWorkItem(new WaitCallback(CallOnArgumentsReceived), arguments.ToArray());
}
}
catch (IOException)
{ } //Pipe was broken
finally
{
ListenForArguments(null);
}
}
/// <summary>
/// Calls the OnArgumentsReceived method casting the state Object to String[].
/// </summary>
/// <param name="state">The arguments to pass.</param>
private void CallOnArgumentsReceived(Object state)
{
OnArgumentsReceived((String[])state);
}
/// <summary>
/// Event raised when arguments are received from successive instances.
/// </summary>
public event EventHandler<ArgumentsReceivedEventArgs> ArgumentsReceived;
/// <summary>
/// Fires the ArgumentsReceived event.
/// </summary>
/// <param name="arguments">The arguments to pass with the ArgumentsReceivedEventArgs.</param>
private void OnArgumentsReceived(String[] arguments)
{
if (ArgumentsReceived != null)
ArgumentsReceived(this, new ArgumentsReceivedEventArgs() { Args = arguments });
}
#region IDisposable
private Boolean disposed = false;
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (mutex != null && ownsMutex)
{
mutex.ReleaseMutex();
mutex = null;
}
disposed = true;
}
}
~SingleInstance()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
}
I call it like this:
private static void Main()
{
Guid guid = new Guid("{6EAE2E61-E7EE-42bf-8EBE-BAB890C5410F}");
//SingleInstance ensures only 1 instance of the app runs at one time. If another instance is started
//it will be closed. If the 2nd instance included arguments these will be passed to
//the singleInstance_ArgumentsReceived event for originally running process
using (SingleInstance singleInstance = new SingleInstance(guid))
{
//MessageBox.Show(Environment.GetCommandLineArgs().ToString());
//if (Environment.GetCommandLineArgs().Contains("RunAsAdmin"))
//MessageBox.Show("YES");
if (singleInstance.IsFirstInstance || Environment.GetCommandLineArgs().Contains("RunAsAdmin"))
{
singleInstance.ArgumentsReceived += singleInstance_ArgumentsReceived;
singleInstance.ListenForArgumentsFromSuccessiveInstances();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
// Show the system tray icon.
//using (ProcessIcon pi = new ProcessIcon())
using (ProcessIcon pi = new ProcessIcon())
{
//Use to pass instance of ProcessIcon to LyncPresenceSwitcher
lyncPresenceSwitcher.processIcon = pi;
//Pass Lync instance
pi.lync = lyncClientController;
pi.Display();
// Make sure the application runs!
Application.Run();
}
}
else
singleInstance.PassArgumentsToFirstInstance(Environment.GetCommandLineArgs());
}
}
//Process arguments past with app execution
private static void singleInstance_ArgumentsReceived(object sender, ArgumentsReceivedEventArgs e)
{
if (settingsBox == null)
return;
foreach (String arg in e.Args)
{
//if arguments include OpenSettings open SettingsBox
if (arg == "OpenSettings")
{
settingsBox.ShowDialog();
}
if (arg == "RunAsAdmin")
{
//singleInstance.Dispose();
}
}
}
The app checks whether settings require admin access and prompts user to restart as admin when required. To restart the app I run this:
if (!IsRunAsAdmin())
{
// Launch itself as administrator
ProcessStartInfo proc = new ProcessStartInfo();
proc.UseShellExecute = true;
proc.WorkingDirectory = Environment.CurrentDirectory;
proc.FileName = Application.ExecutablePath;
proc.Verb = "runas";
proc.Arguments = "RunAsAdmin";
try
{
Process.Start(proc);
System.Environment.Exit(2);
return true;
}
catch
{
// The user refused the elevation.
// Do nothing and return directly ...
return false;
}
The problem is a new instance starts but is closed because of the mutex. Then when I close the original instance I get this:
So I was thinking I could pass an argument to the running instance to tell it to allow a new one to spawn, then close the original. Trouble is I cant figure out how to make this work.
Any help would be very much appreciated :)
p.s. I am a C# novice
Thanks!
The solution is to simply destroy your mutex prior to restarting your application:
mutex.Dispose();

Disposal of AsyncLazy, what is the right (easy to use and non-leaky) way?

I'm using a specialization of Stephen Cleary's AsyncLazy implementation, from his blog.
/// <summary>
/// Provides support for asynchronous lazy initialization.
/// This type is fully thread-safe.
/// </summary>
/// <typeparam name="T">
/// The type of object that is being asynchronously initialized.
/// </typeparam>
public sealed class AsyncLazy<T>
{
/// <summary>
/// The underlying lazy task.
/// </summary>
private readonly Lazy<Task<T>> instance;
/// <summary>
/// Initializes a new instance of the
/// <see cref="AsyncLazy<T>"/> class.
/// </summary>
/// <param name="factory">
/// The delegate that is invoked on a background thread to produce
/// the value when it is needed.
/// </param>
/// <param name="start">
/// If <c>true</c> commence initialization immediately.
/// </param>
public AsyncLazy(Func<T> factory, bool start = false)
{
this.instance = new Lazy<Task<T>>(() => Task.Run(factory));
if (start)
{
this.Start();
}
}
/// <summary>
/// Initializes a new instance of the
/// <see cref="AsyncLazy<T>"/> class.
/// </summary>
/// <param name="factory">
/// The asynchronous delegate that is invoked on a background
/// thread to produce the value when it is needed.
/// </param>
/// <param name="start">
/// If <c>true</c> commence initialization immediately.
/// </param>
public AsyncLazy(Func<Task<T>> factory, bool start = false)
{
this.instance = new Lazy<Task<T>>(() => Task.Run(factory));
if (start)
{
this.Start();
}
}
/// <summary>
/// Asynchronous infrastructure support.
/// This method permits instances of
/// <see cref="AsyncLazy<T>"/> to be await'ed.
/// </summary>
public TaskAwaiter<T> GetAwaiter()
{
return this.instance.Value.GetAwaiter();
}
/// <summary>
/// Starts the asynchronous initialization,
/// if it has not already started.
/// </summary>
public void Start()
{
var unused = this.instance.Value;
}
}
This is great code and I really appreciate how easy it is to use. i.e.
class SomeClass
{
private readonly AsyncLazy<Thing> theThing = new AsyncLazy<Thing>(
() => new Thing());
void SomeMethod()
{
var thing = await theThing;
// ...
}
}
Now my question,
Suppose that SomeClass inherits from a class that implements IDisposable and that Thing implements IDisposable. We'd have skeleton implementation like this,
class SomeClass : SomeDisposableBase
{
private readonly AsyncLazy<Thing> theThing = new AsyncLazy<Thing>(
() => new Thing());
protected override void Dispose(bool disposing)
{
if (disposing)
{
// What do I do with theThing?
}
base.Dispose(disposing);
}
}
So, what do I do with theThing in the Dispose override? Should I extend AsyncLazy<T> to have a new property?
// ...
public bool IsStarted
{
get
{
return this.instance.IsValueCreated;
}
}
// ...
Should I change AsyncLazy<T> to implement IDisposable?
Have I misunderstood and I don't need to worry?
Should I do something else?
Stephen Toub's version of this class inherits from Lazy<Task<T>>, so you get the IsValueCreated property automatically.
Alternatively, you could expose the IsValueCreated property from the private field:
public sealed class AsyncLazy<T>
{
private readonly Lazy<Task<T>> instance;
...
public bool IsValueCreated
{
get { return instance.IsValueCreated; }
}
}
For consistency with the built-in Lazy<T> type, I'd avoid renaming the property to IsStarted.
You can use a bool inside the AsyncLazy<T> initialization to know if theThing has been initialized
class SomeClass : SomeDisposableBase
{
public SomeClass()
{
theThing = new AsyncLazy<Thing>(() =>
{
_isInitialized = true;
return new Thing();
}
}
private bool _isInitialized;
private readonly AsyncLazy<Thing> theThing;
protected override void Dispose(bool disposing)
{
if (disposing && _isInitialized)
{
// Dispose Thing
}
base.Dispose(disposing);
}
}
Although, if this pattern occurs in your code more than once, then i would definitely extend AsyncLazy

How to ensure that my class Initialize method is called only once, what would be the best approach?

I'm currently using Unity IoC Container and here is my AppConfig class. As you can see the Initialize method should be called only once and I have used double lock checking to ensure that.
What would be the best way to implement achieve this if my approach is not the best way?
public interface IAppConfig
{
/// <summary>
/// Gets the admin username.
/// </summary>
/// <value>The admin username.</value>
string AdminUsername { get; }
/// <summary>
/// Gets the admin password.
/// </summary>
/// <value>The admin password.</value>
string AdminPassword { get; }
/// <summary>
/// Initializes this instance.
/// </summary>
void Initialize();
}
/// <summary>
/// A singleton App config which helps reading from web.config
/// its lifetime is controlled by Unity.
/// </summary>
public class AppConfig : IAppConfig
{
#region Fields
/// <summary>
/// the injectable config manager
/// </summary>
private readonly IConfigManager _configManager;
private readonly ILogger _logger;
private static readonly object LockObject = new object();
private static bool _initialized = false;
#endregion
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="AppConfig"/> class.
/// </summary>
public AppConfig(IConfigManager configManager, ILogger logger)
{
this._configManager = configManager;
this._logger = logger;
}
#endregion
#region Properties
/// <summary>
/// Gets the admin username.
/// </summary>
/// <value>The admin username.</value>
public string AdminUsername { get; private set; }
/// <summary>
/// Gets the admin password.
/// </summary>
/// <value>The admin password.</value>
public string AdminPassword { get; private set; }
#endregion
#region Methods
public void Initialize()
{
if (_initialized)
{
throw new ApplicationException("Initialize method should be called only once");
}
lock(LockObject)
{
if (_initialized) return;
var adminUserNameSetting = _configManager.AppSettings[ConfigKeys.AdminUsername];
if (adminUserNameSetting == null)
{
throw new ApplicationException("AdminUsername key not found");
}
this.AdminUsername = adminUserNameSetting.Value;
if (String.IsNullOrWhiteSpace(this.AdminUsername))
{
_logger.LogError("AdminUsername not found");
}
// log
var adminPasswordSetting = _configManager.AppSettings[ConfigKeys.AdminPassword];
if (adminPasswordSetting == null)
{
throw new ApplicationException("AdminPassword key not found");
}
this.AdminPassword = adminPasswordSetting.Value;
if (String.IsNullOrWhiteSpace(this.AdminPassword))
{
_logger.LogError("AdminPassword not found");
}
_initialized = true;
}
}
#endregion
}
In the Unity, I'm using the below code:
// IAppConfig
container.RegisterType<IAppConfig, AppConfig>(new ContainerControlledLifetimeManager(),
new InjectionConstructor(configManager,
logger));
var appConfig = container.Resolve<IAppConfig>();
appConfig.Initialize();
I think an Initalize() method tastes more like an implementation issue. And that means that maybe it shouldn't be in the interface at all.
Initializing an instance is best left to the constructor.
If you really need a delayed Initialize then you solution with a bool and a lock seems OK.
Judging by what you are doing in the Initialize method, I think what you need to look into is registering that class as a singleton and persisting the container. You can see an example of doing this here:
http://gunnarpeipman.com/2008/04/unity-and-singletons/
Okay so you're relying on Unity to ensure that you class is a singleton. Although the code pattern for C# is quite easy. See here. Then call initialisation code in the constructor.
In any case I would declare your initialization flag volatile as the code stands atmo.
I prefer to have a static class instance variable that checks to see if it has been initialized in the get accessor. Access the class through the instance property and you will control how many times the class is initialized. This is pretty much the default C# singleton pattern:
public static class MySingleton
{
private static Mutex instanceLock = new Mutex();
private static MySingleton instance;
public static MySingleton Instance
{
get
{
instanceLock.WaitOne();
if(instance == null)
{
instance = new MySingleton();
}
instanceLock.ReleaseMutex();
return instance;
}
}
private MySingleton()
{
Initialize();
}
private void Initialize()
{
// Initialize
}
}
public class MyOtherClass
{
private MySingleton singleton = MySingleton.Instance;
}

Categories