I am working on a .Net project(solution) which is having 25 projects. I want to set the value in some function/method so that It can be set once for the entire application. Where to set this method so that I dnt need to set it again in the individual winforms. That function/method is in some dll so i required to set that like this:
Logger obj = Logger.GetInstance();
obj.SetLogLevel(1);
I need to use the above code only once.
Kindly help?
Thank You...
Since you talk about pages, I assume you have a web site or a web application.
What you can do, in this case is to create a static class in App_Code and do this in it's static constructor. This way the first time any page accesses the static class the code will run and it won't run again.
public static class AStaticClass {
public static Logger Obj;
static AStaticClass() {
Obj = Logger.GetInstance();
Obj.SetLogLevel(1);
}
}
EDIT:
In case this is a window application, just put this static class in one of the libraries. It doesn't really matter where the class is.
Related
I am a total beginner in C# programming language. I am trying to use Getter and Setter in order to set the string in ProjectA and the retrieve it in Project B.
Project B uses Windows Forms, and I wasnt to set the value of TextBox
with the retrieved string.
Project A is a Console Project and it just reads out some stuff from
file and stores it in string, which I want to retrieve.
However, this is my call in Project B:
string cardOwner = Transmit.Program.CardOwner;
Debug.WriteLine("Card owner = " + cardOwner);
tb_cardholder.Text = cardOwner;
And this is my Getter / Setter in Project A:
private static string _cardOwner;
public static string CardOwner
{
get
{
return _cardOwner;
}
set
{
_cardOwner = value;
}
}
_cardOwner = System.Text.Encoding.ASCII.GetString(bCardOwner);
But in Project B I get "" empty string.
I have included Project A in Project B (added Reference and wrote "using ProjectA").
Any ideas what's going wrong?
Thanks.
Just because you include a project and use its classes in your project B, it doesn't mean that you also use the instances of these classes.
Take the following class:
public class Test
{
public string Message { get; set; }
}
You can put this class into a DLL project (Tools) and reference it from other projects, like a WinForms project ProjectA and a console project ProjectB.
In both projects, you can write something like:
Test t = new Test() { Message = "Hello" };
That creates a new instance of the Test class, but the two running applications ProjectA and ProjectB do not exchange the data! They are completely separated.
The same is true for class properties.
You can't share information between two different applications so easily. Static properties only share data within the same Application Domain, that is in most simple constellations within the same Windows process.
If you want to transfer data between two different processes, you need to use an explicit mechanism for interprocess communication.
When is this line executed?
_cardOwner = System.Text.Encoding.ASCII.GetString(bCardOwner);
You'll need to put that in a method and call that method (and knowing when the call happens will help you understand why _cardOwner is not set:
public static void Init()
{
_cardOwner = System.Text.Encoding.ASCII.GetString(bCardOwner);
}
Then call this method somewhere that you know will be executed before you need _cardOwner:
Transmit.Program.Init();
string cardOwner = Transmit.Program.CardOwner;
tb_cardholder.Text = cardOwner;
I just started working in C# after working in VB.Net for a while. I have a dll that contains frequently used database connection strings (and some other db info) and another dll that contains frequently used directory paths. When creating an application in VB, I would use these dlls in a Module to set the environment to testing so the databases would point to the QA versions of the databases and the directories would point to my local directories. When I was ready to publish the application, I would set the environment to production. It looked something like this.
Module MyModule
Friend MyBizDBs As BizDBs
Friend MyBizPaths As BizPaths
Friend TodaysDate As Date
Friend Sub InitializeModule()
MyBizDBs = New BizDBs(DBReference.BizDatabases.DBConfig.DB_Environment.QA)
MyBizPaths = New BizPaths(BizPaths.PathEnvironment.Test)
TodaysDate = DBReference.BizDatabases.DBMethods.GetTodaysDate
End Sub
End Module
I could then call InitializeModule at the start of the application and whenever a class needed a connection string or a directory or anything else offered by those dlls, it would be pointing to the correct environment. Moreover, I didn't need to create a new instance of MyModule each time. Instead I could simply write:
Using sw as new StreamWriter(MyBizPaths.ReconciliationReport)
I know C# doesn't have Modules. I know static classes are similar, but I can't initialize the objects (MyBizDBs and MyBizPaths) to set them to the appropriate environment in static classes. I'm looking at a C# Singleton, but that reinitializes each time the class is called. Is there a better way to achieve what I'm trying to do in C#?
Thanks!
EDIT: Here is what the singleton looks like in C#.
public sealed class MySingleton
{
private static readonly MySingleton instance = new MySingleton();
private MySingleton() { }
public static MySingleton Instance
{
get
{
return instance;
}
}
public BizPaths MyBizPaths = new BizPaths(BizPaths.PathEnvironment.Test);
public BizDBs MyBizDBs = new BizDBs(DBConfig.DB_Environment.QA);
public DateTime todaysDate = DBMethods.GetTodaysDate();
}
There's only one way to emulate a VB module in C# and that's with a static class. Once compiled, a VB module IS a static class, so obviously that's what you should use in C# if you want the same behaviour as a VB module. The difference is that module members don't have to be qualified with their type name in VB, while C# static class members do require qualification.
Initially, I think PowerShell instantiate one class only when the cmdlet tagged on this class is called. On execution, each cmdlet falls into the BeginProcess -> ProcessRecord -> EndProcess(StopProcess) path, and after the EndProcess is done, it seems the process will end and then the memory will collect all these class objects as garbage.Therefore each class should live in their own life cycle and not share any resources. When we are calling these cmdlets,
However I find that classes do share the same static values in the same module. For example, assume in my project I have two classes:
namespace PSDSL
{
[Cmdlet(VerbsCommon.Get, "MyTest")]
public class GetMyTest : Cmdlet
{
public static GlobalUserName = "";
[Parameter(Mandatory = false)]
public string Filepath { get; set; }
protected override void InnerProcessRecord()
{
if (_filepath != null)
{
GlobalUserName = _filepath;
}
Console.WriteLine(GlobalUserName);
}
}
}
namespace PSDSL
{
[Cmdlet(VerbsCommon.Get, "MyTest2")]
public class GetMyTest2 : Cmdlet
{
[Parameter(Mandatory = false)]
public string Filepath { get; set; }
protected override void InnerProcessRecord()
{
if (_filepath != null)
{
GlobalUserName = _filepath;
}
Console.WriteLine(GlobalUserName);
}
}
}
The two commands are pretty similar except one defines a static GlobalUserName. Calling these 2 cmdlets shows that the GlobalUserName can be read\write from both cmdlets.
My confusion is that, when are the classes be instaniated?
Whole assembly loaded at once and stays loaded till restart of the PowerShell prompt.
Details:
Smallest unit of code isolation in .Net is Assembly (in most cases single managed DLL).
Process that uses managed runtime can't load less than single assembly at a time - so all classes from that assembly (and related once on demand) will be loaded together. As result all static fields will be present at the same time in memory (note that static fields are initialized "before first use of the class" which mean they are not necessary initialized on load of the assembly).
There also no way to "unload" class or even assembly without using separate AppDomains. PowerShell does not use multiple AppDomains to load assemblies for different modules (generally cross-AddDomain calls require special attention during implementation and you'd know about it by now). As result once loaded module stays in memory till you quit PowerShell (covered in Powershell Unload Module... completely).
Since assembly is loaded once for all commandlets in it all static fields will be present at once and keep they values till exiting of PowerShell.
Side note: I'd strongly recommend avoiding static fields for anything but really static immutable data in general. It is way to easy to leave some random values there and impact future code. In PowerShell pipeline is the way to pass information between commandlets, other types of processes (WinForms, ASP.Net,...) have they own preferred mechanism to pass data instead of using static.
I am using several class libraries within a project, and one of them is a typical "project.common.dll" library containing some common helper functions. One of these functions is a debug function that creates debug output.
Now I would like to enable/disable debug output by using a user-level property (application settings). How can I reference variables defined in main application's program.cs within this class library ?
Update : Thanks all. I will probably create a static method in my base application that performs the check (to debug or not) and then calls the Debug function in the common library.
You can't.
What you will need to do is have the properties in the class library itself and when you create the instance of it in your main application pass the user setting in:
var debug = new DebugInstance { Output = this.Output };
or set the parameters if it's a static class:
StaticDebug.Output = this.Output;
You can use the ConditionalAtrribute:
[Conditional("DEBUG")]
public static void WriteDebugInfo()
{
Trace.WriteLine("what ever...")
}
This way when you build in Debug mode, the method is invoked; in Release mode not.
Use parameters on the constructor of the Debug class (or a static constructor if the class is static).
I have a WinForm project that contains several UserControls. This WinForm project has a reference to an assembly (lets call it lib.dll) that is created from another project (Class Library) that exists in a different solution.
Now, several of the UserControls make calls into lib.dll that return values from the app.config file. At runtime lib.dll works fine and returns the necessary data but at design time, I am getting an exception from lib.dll because the app.config sections are NULL (the exceptions are by design).
Now I could go through each control and wrap any code that calls into lib with
if(!DesignMode) { //code }
But that is a lot of controls to go and apply that to. Is there something I can do globally that would be more elegant then testing the DesignMode property?
Edit
In response to the two comments left below: the solutions provided don't appear to work. The assembly that is causing me a problem lives in the same directory as the app.config. The general directory structure looks like this
References Folder
Configurations (Folder)
appsettings.config
app.config
lib.dll
app.config pulls in several other config files (appsettings, cnx strings, etc) which reside in the Configurations directory. In the case of my exception the value I am trying to get resides in one of these ancillary config files that is referenced by app.config.
This is an interesting question. A solution could be to create in lib.dll a static class like this one :
public static class Config
{
private static readonly _param1;
static Config()
{
_param1 = ConfigurationManager.AppSettings["Param1"] ?? "Your default value";
}
public static string Param1
{
get { return _param1; }
}
}
Then, in your code, insted of writing ConfigurationManager.AppSettings["Param1"], you will use Config.Param1. So you won't need to test the property DesignMode.
There are so many ways to do this, IMHO.
One thought that immedidately comes to mind would be to use an inheritance-based approach for the user controls in question? That way, in the base class, you can put that if (DesignMode) check in, and do the correct branching from there.
// if i were to visualizeyour lib.dll data initializer call like this:
class BaseUserControl
{
// i'm guessing that you initialize the data somehow...
void InitializeData()
{
if (!DesignMode)
{
InitializeDataLocal();
}
}
protected virtual InitializeDataLocal()
{
// whatever base behavior you want should go here.
}
}
// in the derived classes, just put the code you currently have for
// fetching the data from lib.dll here...
class UserControl : BaseUserControl
{
protected override InitializeDataLocal()
{
// fetch from lib.dll...
// optionally invoke some base behavior as well,
// if you need to...
base.InitializeDataLocal();
}
}