Static property won't stay set? - c#

I want to share a property between two projects in the same solution, so I created a simple static class in a separate (third) project with a static property. However, when I set it in one project, the change doesn't seem to occur when I try to get the value of the property from the other project.
Since the property is static shouldn't there only be one instance of it? I've debugged and the value is indeed set after the assignment statement, why doesn't this apply when its referenced in the other project?
Here's the code:
namespace Shared
{
public static class Shared
{
public static string old { get; set; }
}
}
Assignment statement in first project
Shared.Shared.old = messageData.Items[0].DateTime;
Trying to access property in 2nd project
if (messageData.Items[0].DateTime.CompareTo(Shared.Shared.old) > 0)

A static property has one instance per process (technically, per AppDomain). If you're trying to share it between two executables, each process will get a unique value.
If you want to communicate between two executables, you'll need to use some form of Interprocess Communication, or serialize to some external source (the file system, a database, etc).

Related

Accessing an object anywhere in the application (C#/WPF)

I'm deserializing an XML document into a custom object and I need that data to be available anywhere in the entire application.
I instantiate this public class in MainWindow.xaml.cs and I can't figure out how to access that object from other UserControls and ViewModels.
What are some best practices and examples?
Think of this object as holding all of my application's data that I want to be able to read from, update, and save from any screen. (Some of the data can be complex so I don't want to store it in settings. I need to read and write to the XML file.)
Thanks!
You can achieve this by e. g. implement a static class that manages your custom implementation, including serialization/deserialization.
public static class Config
{
public static YourCustomType Data { get; private set; }
public static void LoadXml()
{
Data = YourDeserializationLogic();
}
public static void SaveXml()
{
YourSerializationLogic(Data);
}
}
And if you want to use the full power of notify change propagation, you may consider using separate properties of type ObservableCollection<T> in your static class:
public static ObservableCollection<AnotherCustomType> ObservableData { get; private set; } = new ObservableCollection<AnotherCustomType>();
Just be sure that in your LoadXml() logic you have to populate these properties item by item, for the ObservableCollection to emit events:
public static void LoadXml()
{
...
foreach (YourType item in YourData)
{
ObservableData.Add(item);
}
}
I favor this option compared to e. g. a singleton, because I have full control of when in the startup sequence Config.LoadWhatever() is called.
This is important for me, because I like to have logging for the configuration load (which may be implemented via singleton as well, yes - but IMHO the principle of singletons is void, if the respective instances are always created in a fix place in the startup sequence - though I am happy to learn additional advantages if there are some).
What I have done is use a service that holds current data or whatever you want to call it. I inject it into the classes as a singleton so all classes have the same reference. In web client side it's referred to as a data store.

How to structure a .Net projects? Common code, shared by different projects

I am using same constants in two different project in different visual studio solutions.
Project 1 is ASP.NET WEB API and
Project 2 is client web application.
Constants example:
1. BUYING_RATE
2. THRESHOLD_LIMIT
etc
My question is.
Should I create a new library project just for handling constants and share this dll in both projects? I want to avoid
duplacate code in two different projects
Note 1: I cannot add both projects (API project and client project) in one solution due to some limitations so ignore this
Note 2: Both projects are managed by me
One more scenario is. ASP.NET WEB API will be consumed by 3rd parties as well. So should I provide the dll-s to them or API documentation is enough.
Or Am i thinking wrong about the design. If yes have a better solution, then what other options are to solve this problem
Thanks in advance
You can use a NuGet to share constants but I wouldn't. The main problem is that you will have to plan your constants beforehand or the NuGet publication will delay your progress.
When using a shared library, consider using variables instead of constants. It often happens that you need to change a constant value and you do not want to issue a full rebuild. Constant values are compiled into the assemblies referencing them. Variables get evaluated at run-time.
When making a shared library, consider providing a statically accessible instance container. It is often usable to provide different semi-constant value sets for different reader instances.
//Constant-provider assembly code. Separate library that is.
public class MyConstants
{
//Gets compiled into user code. Changing value -> rebuild all clients.
//public const double BUYING_RATE = 0.5;
//Gets evaluated in run-time. Changing value -> clients get new value.
public readonly double BUYING_RATE = 0.5;
private static MyConstants _default;
static MyConstants()
{
_default = new MyConstants();
}
//Provide default instance. You can change it in run-time when needed.
public static Default
{
get
{
return _default;
}
}
}
//Constant-user assembly code. Sample usage code for reader assemblier.
private class User
{
public void Method1()
{
... = MyConstants.Default.BUYING_RATE;
}
}

How to share data between Service Project (WCF) and another project

(Edited) -> I have a solution with different projects. It has a strange structure because I'm not an professional software engineer. The solution has three parts: one HMI project (WPF), bussiness project (class library type) and service project (WCF).
In the bussiness project, I do some process that has result which I save in a static class. This results are exposed in the screen by WPF project mentioned previously and now I need to transfer this data by one service placed in the WCF project.
The object is similar to:
[DataContract]
public class ObjectToTransfer
{
[DataMember]
public string ParameterOne = string.Empty;
[DataMember]
public string ParameterTwo = string.Empty;
}
In the other hand, the method that picks up the informtion from static class belonging to bussiness project is like this:
[ServiceBehavior]
public class Service: IService
{
public ObjectToTransfer SendObject()
{
return new ObjectToTransfer{
ParameterOne = BusinessProject.StaticClass.ResultOne,
ParameterTwo = BusinessProject.StaticClass.ResultTwo
};
}
Well, when I consume the service the result is a object with the parameters one and two empty. In additon, when I debug the solution with both projects run, the static class hasn't info in her atributes... It's like whether both projects run independently, in spite of both are under the same solutions..., It's like whether there was no relationship between them. Where is the mistake?
Thank you in advance!
The main thing you will need to do is change the DataContract class to a class with proper getters and setters.
[DataContract]
public class ObjectToTransfer
{
[DataMember]
public string ParameterOne { get; set; }
[DataMember]
public string ParameterTwo { get; set; }
}
The reason this is important is because of the way WCF works when it try to serialize the data from the server to the client. Essentially, the class on the server side schematically matches a generated class on the client. (They share the same class schema.) If there is no proper structure to the class, the data cannot get set. The members are basically read-only.
What you have in your class right now are public member variables, and they are set to always return string.Empty. WCF can't work with that, it is too strict. The server and the client need to be able to read and write to all DataMember properties, so you need the { get; set; }.
Don't forget to refresh your service reference after making this change.
If you need some good resources to learn WCF, check out these videos WCF Tutorial. They are a little dated, but all of the concepts still apply.
This might be late and I am new to WCF service, so I am sharing based on what I have done in my case to share data among different projects.
Background of my project:
I have a WCF service(host), a client and a server project. (A total of 3 different projects.) I will perform the necessary calculation in WCF service. Afterwards, I am suppose to share the result to the client and server. Therefore, there is this variable, variableA, that I have share among the 3 projects.
What I did:
In WCF service, I declare variableA and mark it static:
private **static** string variableA;
Only after I marked variableA as static, then I can see the same variableA across different projects.
I am not sure if this helps but this is what I did in my case.

Accessing an instance of an object from a different application

I'm working on a program where i have to read several excel files to populate an instance of an object of a complex class. It has many methods and properties of different types, from double to nested lists of objects from other custom classes in the project. Is there a way to store the instance i created for future reference? I want to use that specific instance in a different project without reading all the excel files again.
For example let my class be Book.cs.
public class Book
{
public string title;
public string author;
public string publisher;
public int publishYear;
public int pages;
public LibraryRef refInfo; //another custom class with properties.
}
There's also a method that reads an excel file and sets the properties above. Then in Main i create an instance of Book class.
Book b = new Book();
b.ReadExcelFile("excelFile"); //sets the properties of the instance.
I want to be able to access the values of the properties of b from a different project, anytime i want.
You could implement a in-memory shared cache for your project during it's runtime and access the cached object if it's from another module in the same application.
Since it's a different application, there would be no shared memory. So your best bet to avoid parsing the excel file is to serialize the object into a file (in a common file location) and deserialize it back. If you are not keen on using a file system, you could also use azure blob storage.
See Binary Formatter Usage for Serialization and Deserialization.
http://msdn.microsoft.com/en-us/library/system.runtime.serialization.formatters.binary.binaryformatter(v=vs.110).aspx

Is it possible to pass a App setting in the web.config to a Common C# class

Is it possible to pass a App setting "string" in the web.config to a Common C# class?
In any class you can use ConfigurationManager.AppSettings["KeyToSetting"] to access any value in the element of web.config (or app.config)
Of course it's possible - but the thing to keep in mind is that a properly designed class (unless it's explicitly designed for ASP.NET) shouldn't know or care where the information comes from. There should be a property (or method, but properties are the more '.NET way' of doing things) that you set with the string value from the application itself, rather than having the class directly grab information from web.config.
If you have configuration values that are used in many places consider developing a Configuration class that abstracts the actual loading of the configuration items and provides strongly typed values and conversions, and potentially default values.
This technique localizes access to the configuration file making it easy to switch implementations later (say store in registry instead) and makes it so the values only have to be read from the file once -- although, I would hope that the configuration manager would be implemented this way as well and read all values the first time it is used and provide them from an internal store on subsequent accesses. The real benefit is strong typing and one-time-only conversions, I think.
public static class ApplicationConfiguration
{
private static DateTime myEpoch;
public static DateTime Epoch
{
get
{
if (myEpoch == null)
{
string startEpoch = ConfigurationManager.AppSettings["Epoch"];
if (string.IsNullOrEmpty(startEpoch))
{
myEpoch = new DateTime(1970,1,1);
}
else
{
myEpoch = DateTime.Parse(startEpoch);
}
}
return myEpoch;
}
}
}

Categories

Resources