Here is the problem. I made a class of enums to track difficulty level. When I pass the level in my main It does not get passed into my OtherPage. here is my code public sealed class GlobalVars
{
public enum Difficulty
{
Easy,
Intermediate,
Hard
}
private static readonly GlobalVars instance = new GlobalVars();
private GlobalVars() { }
public static GlobalVars Instance
{
get
{
return instance;
}
}
}
Here is what I am doing in my main page
private void Easy_Checked(object sender, RoutedEventArgs e)
{
GlobalVars.Difficulty _difficulty = GlobalVars.Difficulty.Easy;
//_difficulty = GlobalVars.Difficulty.Easy;
}
Next I go to my divisionPage and do the following
initialize an instance of the class
private GlobalVars.Difficulty _difficulty;
then
if ( _difficulty == GlobalVars.Difficulty.Easy)
{
do something easy
}
if ( _difficulty == GlobalVars.Difficulty.Hard)
{
do something hard
}
My enum value is always easy not able to pass the other levels to this page.
First of all, you not are using Enum incorrectly. Difficulty is an enum(type).
Second, you are not using the GlobalVars instance at all, you are always working with a local variable. Instance property has to be used to use the instance and then set the values at the level of instance.
GlobalVars.Difficulty _difficulty = GlobalVars.Difficulty.Easy;
Above statement assigns value to only the variable _difficulty but not to the static instance. If you need to carry the state or set the difficulty value, use some instance\member level variable like,
public Difficulty DifficultySet { get; set; }
Set the instance's DifficultySet from MainPage, access this value from any other page. Since you have singleton (one instance only), value set from Main page would be available with the instance.
Complete code would look like below. [Please write your own code to understand, how static, enums and instantiation works.]
public sealed class GlobalVars
{
static readonly GlobalVars instance = new GlobalVars();
public Difficulty DifficultySet { get; set; }
private GlobalVars()
{
}
public static GlobalVars Instance
{
get
{
return instance;
}
}
public enum Difficulty { Easy, Intermediate, Hard };
}
//main page
GlobalVars pageInstance = GlobalVars.Instance;
pageInstance.DifficultySet = GlobalVars.Difficulty.Easy;
//other page
if(GlobalVars.Instance.DifficultySet == GlobalVars.Difficulty.Easy)
{
//write your logic
}
Related
I have a Configuration class that stores certain variables which serve as settings. And I'm struggling to find easiest and most optimal way to save it to file - would be weird if user had to configure it every time.
Example class:
public static Configuration
{
public static bool A = false;
public static bool B = false;
public static int C = 100;
}
Serializing collection is not an issue, but i cannot really make collection out of these variables, since they have not matching data types.
I'm certain solution is simple, but for some reason I'm stuck here.
Elaborating on my comment, you're better off converting your static class into an instance class for minimizing manual coding to store/read the property values in the future. This refactoring can be done in minutes. So do that as a first step, it shouldn't take too long to do, and a simple "Find/Replace" can fix all of your declarations everywhere in your code where you previously used "Configuration".
Keep your implementation static, but change to a single instance that you are accessing.
public class Configuration
{
private static Configuration instance;
public static Configuration Instance
{
get
{
if (instance == null)
{
instance = new Configuration();
}
return instance;
}
set
{
instance = value;
}
}
public bool A { get; set; }
public bool B { get; set; }
public int C { get; set; }
}
Do a Find/Replace where ever you declared your static class and replace "Configuration." with "Configuration.Instance.". Also, where you previously declared static properties like public static bool A; public static bool B; ... just select all of the text, do a Find/Replace and replace "static " with "".
Save/Read your data
// To Save
File.WriteAllText(#"c:\temp\myconfig.json", Newtonsoft.Json.JsonConvert.SerializeObject(Configuration.Instance));
// To Read
using (var file = File.OpenText(#"c:\temp\myconfig.json"))
{
JsonSerializer serializer = new JsonSerializer();
Configuration.Instance = (Configuration)serializer.Deserialize(file, typeof(Configuration));
}
I have a struct called Services and in it I have some static properties
public struct Servico
{
public static Servico Instalacao {
get { return new Servico(ServicesType.Instalacao); }
}
public static Servico Desativacao {
get { return new Servico(ServicesType.Desativacao); }
}
public static Servico TrocaVeiculo {
get { return new Servico(ServicesType.TrocaVeiculo); }
}
public static Servico TrocaTitularidade {
get { return new Servico(ServicesType.TrocaTitularidade); }
}
}
How to list all my properties when I declare an object. Same when we declare a color, automatically all colors are listed.
Example:
Some object-oriented languages allow one to access a static member through an instance.
C# however does not. While from within the class or struct (or one derived from it) you can call a static method or access a static field or property directly just as you can an instance method, from outside of it you must use the name of the class or struct.
Hence e.g.:
var foo = Servico.Instalacao;
The intellisense is geared towards helping you write reasonable code. As such if you write the above as far as:
var foo = Servico.
Then it should list the static members at that point.
I'm building a WinForms application using C# 2.0 for a Job Scheduler.
Wrote a public class Job in Program.cs defining the Job object.
//Class for defining Job object and its properties
public class Job
{
private int IntJobID;
public int JobID
{
get {return IntJobID;}
set {IntJobID = value;}
}
private string StrJobName;
public string JobName
{
get { return StrJobName; }
set { StrJobName = value; }
}
//Several other properties defined here.
}
Also wrote a public static class ApplicationName in Program.cs for containing application-wide config variables and all helper methods.
//Static Class for Global Properties and Global Methods
//*****************************************************
public static class ApplicationName
{
//Global Properties
//***************************
public static string ConfigFilePath = "D:\\ApplicationName\\conf\\ApplicationName.ini";
public static string DBFilePath = "D:\\ApplicationName\\data\\ApplicationName.xml";
//Global Methods
//************************
public static void HelperMethod1(Args)
{
}
public static string HelperMethod2(Args)
{
}
public static Job GetJobByID(int JobID)
{
XmlDocument XMLDB = new XmlDocument(); XMLDB.Load(DBFilePath);
Job ObjJob = new Job();
ObjJob.JobName = XMLDB.SelectSingleNode("/ApplicationName/Job[JobID=" + JobID.ToString() + "]/JobName").InnerText.Trim();
//Several other properties are retrieved from the DB and set to the object here.
return ObjJob;
}
}
One of the helper methods GetJobByID in the public static class ApplicationName is required to create/instantiate a Job object and return the same. I believe this is possible, a method within ClassA creating and returning an instance/object of ClassB.
Note: This method is meant for access from other forms such as Form1.cs, Form2.cs, etc. in the following way. To my knowledge, this is also allowed and is accepted practice.
private void FormAddEditJob_Load(object sender, EventArgs e)
{
int SelectedJobID = Convert.ToInt32(this.Tag);
//Creating an instance of the Job Class
//Assigning the value of the Job object returned by GetJobByID method
Job JobToEdit = ApplicationName.GetJobByID(SelectedJobID);
TextBoxJobID.Text = SelectedJobID.ToString();
TextBoxJobName.Text = JobToEdit.JobName;
}
PROBLEM: The object returned by GetJobByID method is not getting stored in the object reference JobToEdit. Or even possible that the GetJobByID method does not return an object appropriately / as expected. What am I doing wrong here? Is this not the right way to return an object?
Issue identified and resolved.
One of the statements ObjJob.PropertyName = XMLDB.SelectSingleNode() in the GetJobByID method was throwing an exception, due to fetching null values from the DB, thereby resulting in the ObjJob object being returned as null. Found this by debugging line by line.
I want to be able to store code in a database and then execute it dynamically (using Roslyn). However, I want to be able to (inject?) properties from calling code. See below:
using Roslyn.Scripting.CSharp;
using RoslynMVCTest.Interfaces;
namespace RoslynMVCTest.Services
{
public class MyService
{
private readonly IInjectedService _injectedService;
public MyService(IInjectedService injectedService)
{
_injectedService = injectedService;
}
public bool SomeMethod()
{
string codeString = #"
using RoslynMVCTest.Interfaces;
public class SomethingDoer
{
public IInjectedService InjectedService {get;set;}
public static bool DoSomething()
{
return IInjectedService.SomeOtherMethod();
}
}";
var engine = new ScriptEngine();
var session = engine.CreateSession(_injectedService);
session.AddReference(this.GetType().Assembly);
//How do I set the property in my dynamic code to _injectedService??
var result = session.Execute<bool>("SomethingDoer.DoSomething()");
return result;
}
}
}
I realize there are probably syntax and other issues here, but it's a good representation of what I want to do. Is there a way to do this?
First I'm going to answer your question matching your original code as closely as possible. Second, I'm going to show a far more concise example that might in fact be all that you're after.
You can certainly declare your type as you've done, but a few things will have to be fixed to even get it to make sense.
Your SomethingDoer class declares a non-static InjectedService property, despite the fact that you attempt to consume that property in a static method. I will assume for the sake of discussion that you intended SomethingDoer.DoSomething to be non-static as well and will thus instanatiate that class.
public static bool DoSomething()
To:
public bool DoSomething()
The "sesion" you pass to CreateSession is your actual service. To understand why this won't work, you have to understand what the argument you pass to CreateSession means and what's done with it. What the "session" means is that all the public properties of that object are available to your scripting session as raw identifiers without the need to . reference them on any target. Thus, to get your code working, I've introduced a new class (inner to the main service class for convenience) called Session:
public class Session
{
public IInjectedService InjectedService { get; set; }
}
Furthermore, I've used this new class when invoking CreateSession:
var session = engine.CreateSession(new Session { InjectedService = _injectedService });
What this means is that the property InjectedService is now available to you within your codeString.
Perhaps most importantly, your code codeString is never actually consumed by your code! You seem to have, understandably, conceived of this process as setting up a string for your code, and then imagined that you could then invoke some arbitrary method within it. On the contrary, there is only one block of code. So if you really want to declare a whole class in your script-code, you're still going to have to consume it directly within your script-code as well. This means that the final two lines of your codeString should actually look like:
var somethingDoer = new SomethingDoer { InjectedService = InjectedService };
somethingDoer.DoSomething()";
Here we're instantiating SomethingDoer (because of change 1.) and setting the service property by the implicit InjectedService value provided by the session (because of change 2.).
For completeness, here is the fully working sample code:
namespace RoslynMVCTest.Interfaces
{
public interface IInjectedService
{
bool SomeOtherMethod();
}
}
namespace RoslynMVCTest.Services
{
using RoslynMVCTest.Interfaces;
class Program
{
static void Main(string[] args)
{
Console.WriteLine(new MyService(new InjectedService()).SomeMethod());
Console.ReadLine();
}
}
class InjectedService : IInjectedService
{
public bool SomeOtherMethod()
{
return true;
}
}
public class MyService
{
private readonly IInjectedService _injectedService;
public MyService(IInjectedService injectedService)
{
_injectedService = injectedService;
}
public class Session
{
public IInjectedService InjectedService { get; set; }
}
public bool SomeMethod()
{
string codeString = #"
using RoslynMVCTest.Interfaces;
public class SomethingDoer
{
public IInjectedService InjectedService { get; set; }
public bool DoSomething()
{
return InjectedService.SomeOtherMethod();
}
}
var somethingDoer = new SomethingDoer { InjectedService = InjectedService };
somethingDoer.DoSomething()";
var engine = new ScriptEngine();
var session = engine.CreateSession(new Session { InjectedService = _injectedService });
session.AddReference(this.GetType().Assembly);
//How do I set the property in my dynamic code to _injectedService??
var result = session.Execute<bool>(codeString);
return result;
}
}
}
Alternative Approach
If all you want to do is allow your script to run some code that interacts with your service, you can see how this is actually extremely trivial given all the points made above. Thus to concisely express what might be the intent of your original code, all you'd have to do is:
var result = session.Execute<bool>("InjectedService.SomeOtherMethod()");
The code passed in here is simply the body of the service method in the long-winded first example. Quite possibly this is all you need or want.
I have just recently got involved in a classic ASP.NET project which contains lots of storing and reading values from the session and query strings. This could look something like the following:
Session["someKey"]=someValue;
And somewhere else in the code the value in the session is read. Clearly this violates the DRY principle since you'll have the literal string key spread out all over the code. One way to avoid this could be to store all keys as constants that could be referenced everywhere there is a need to read and write to the session. But I'm not sure that's the best way to do it. How would you recommend I best handle this so that I don't violate the DRY principle?
Create a separate public class where you can define your constants, e.g
public class SessionVars
{
public const string SOME_KEY = "someKey";
public const string SOME_OTHER_KEY = "someOtherKey";
}
and then anywhere in your code you can access session variables like this:
Session[SessionVars.SOME_KEY]=someValue;
This way you can get IntelliSence and other bells and whistles.
I think you're reading too much into DRY. I pertains more to things that could be wrapped up in a function. I.e. instead of repeating the same fives lines all over the place wrap those 5 lines in a function and call the function everywhere you need it.
What you have as an example is just setting a value in a dictionary (the session object in this case), and that is the simplest way to store and retrieve objects in it.
I can't remember for the life of me where I humbly re-purposed this code from, but it's pretty nice:
using System;
using System.Web;
namespace Project.Web.UI.Domain
{
public abstract class SessionBase<T> where T : class, new()
{
private static readonly Object _padlock = new Object();
private static string Key
{
get { return typeof(SessionBase<T>).FullName; }
}
public static T Current
{
get
{
var instance = HttpContext.Current.Session[Key] as T;
lock (SessionBase<T>._padlock)
{
if (instance == null)
{
HttpContext.Current.Session[Key]
= instance
= new T();
}
}
return instance;
}
}
public static void Clear()
{
var instance = HttpContext.Current.Session[Key] as T;
if (instance != null)
{
lock (SessionBase<T>._padlock)
{
HttpContext.Current.Session[Key] = null;
}
}
}
}
}
The idea behind it two fold. The type created should be the only type you need. It's basically a big strongly-typed wrapper. So you have some object you want to keep extending information in:
public class MyClass
{
public MyClass()
public string Blah1 { get; set; }
}
Then down the road you extend MyClass and you don't want to have to remember all the Key Values, store them in AppSettings or Const variables in Static Classes. You simply define what you want to store:
public class MyClassSession : SessionBase<MyClass>
{
}
And anywhere in your program you simply use the class.
// Any Asp.Net method (webforms or mvc)
public void SetValueMethod()
{
MyClassSesssion.Current.Blah1 = "asdf";
}
public string GetValueMethod()
{
return MyClassSession.Current.Blah1;
}
Optionally you could place the access to this session object in a base page and wrap it in a property:
class BasePage : Page
{
...
public string MySessionObject
{
get
{
if(Session["myKey"] == null)
return string.Empty;
return Session["myKey"].ToString();
}
set
{
Session["myKey"] = value;
}
}
...
}
Here you are repeating the myKey string but it is encapsulated into the property. If you want to go to the extreme of avoiding this, create a constant with the key and replace the string.