I have this project:
And I need to use a variable that is in the "TransactionHandler.cs" in the "Enviar Faturas.cs" the TransactioHandler is a class library and the Enviar Faturas is a Windows Form.
Is it possible to do what I want? If so how should I do it?
UPDATE:
I have this variable declares in TransactionHandler.cs
var numfatura = _transaction.TransDocument + _transaction.TransSerial + _transaction.TransDocNumber;
And I need to use it on the Windows Form "Enviar Faturas".
UPDATE 2:
I have this code to select from a datagridview and write a textfile:
FileInfo arquivo = new FileInfo(#"C:\Users\HP8200\Desktop\faturas\" + r.Index + ".txt");
And I want to change the "r.index" for the variable I showed on the first update
I would suggest to use a property instead of a public field:
public class TransactionHandler
{
private static string numfatura = _transaction.TransDocument + _transaction.TransSerial + _transaction.TransDocNumber;
public static string Numfatura
{
get { return numfatura ; }
set { numfatura = value; }
}
}
From another class, you call your variable like this:
public class EnviarFaturas
{
public void DoSomething()
{
string r.Index= TransactionHandler.Numfatura;
}
}
Ok, from what I understand and having no idea of the execution flow you probably need something like this in the TransactionHandler (a property)
public int Numfatura
{
get
{
return this._transaction.TransDocument + this._transaction.TransSerial + this._transaction.TransDocNumber;
}
}
you can change the type to the one that stands behing the "var" in your code example.
To access it in the form you need an instance of the class (again I dont know what your logic is) but once you get it e.g.
var transactionHandler = new TransactionHandler();
you can simply try
r.Index = transactionHandler.Numfactura;
Keep in mind that you can hit the default data value (for int is 0) if your methods depend upon other event to happen.
I strongly suggest you to learn more about C# and Object Oriented Programming as Alexey Zimarev stated in the comments.
Also you should consider how to get/inject a concrete instance in the view.
Another good and related read will be singleton pattern, mvp and dependency injection.
Related
On my form I have a button click
private void button1_Click(object sender, EventArgs e)
{
do something
}
How on the click would I load my do something from a text file, for example my text file looks like this:
MessageBox.Show("hello");
label1.Text = "Hello";
on click it does everything in my text file, if possible.
Here is a very simple example, just to prove this is possible. Basically, you use CodeDomProvider to compile source at runtime, then execute using reflection.
var provider = CodeDomProvider.CreateProvider("C#");
string src=#"
namespace x
{
using System;
public class y
{
public void z()
{
Console.WriteLine(""hello world"");
}
}
}
";
var result = provider.CompileAssemblyFromSource(new CompilerParameters(), src);
if (result.Errors.Count == 0)
{
var type = result.CompiledAssembly.GetType("x.y");
var instance = Activator.CreateInstance(type);
type.GetMethod("z").Invoke(instance, null);
}
Edit
As #Agat points out, the OP seems to require a sort of scripting framework (it makes use of label1, a property of the current object), whereas my answer above obviously does not provide that. The best I can think of is a limited solution, which would be to require dependencies to be specified explicitly as parameters in the "script". Eg, write the scripted code like this:
string src = #"
namespace x
{
using System.Windows;
public class y
{
public void z(Label label1)
{
MessageBox.Show(""hello"");
label1.Text = ""Hello"";
}
}
}
";
Now you can have the caller examine the parameters, and pass them in from the current context, again using reflection:
var result = provider.CompileAssemblyFromSource(new CompilerParameters(), src);
if (result.Errors.Count == 0)
{
var type = result.CompiledAssembly.GetType("x.y");
var instance = Activator.CreateInstance(type);
var method = type.GetMethod("z");
var args = new List<object>();
// assume any parameters are properties/fields of the current object
foreach (var p in method.GetParameters())
{
var prop = this.GetType().GetProperty(p.Name);
var field = this.GetType().GetField(p.Name);
if (prop != null)
args.Add(prop.GetValue(this, null));
else if (field != null);
args.Add(field.GetValue(this));
else
throw new InvalidOperationException("Parameter " + p.Name + " is not found");
}
method.Invoke(instance, args.ToArray());
}
Like the other answers have stated, it isn't an easy thing to implement and can possibly be done through reflection depending on how advanced your scripts are.
But no one #BrankoDimitrijevic mentioned Roslyn and it is a great tool. http://msdn.microsoft.com/en-us/vstudio/roslyn.aspx
It hasn't been updated in quite awhile (Sept.2012) and doesn't have all of the features of C# implemented, however, it did have a lot of it implemented when I played around with this release.
By adding your assembly as a reference to the scripting session, you're able to gain access to all of your assembly's types and script against them. It also supports return values so you can return any data that a scripted method generates.
You can find what isn't implemented here.
Below is a quick and dirty example of Roslyn that I just wrote and tested. Should work right out of box after installing Roslyn from NuGet. The small bloat at the initialization of the script engine can easily be wrapped up in a helper class or method.
The key is passing in a HostObject. It can be anything. Once you do, your script will have full access to the properties. Notice that you just call the properties and not the host object in the script.
Basically, your host object will contain properties of the data you need for your script. Don't necessarily think of your host object as just a single data object, but rather a configuration.
public class MyHostObject
{
public string Value1 { get; set; }
public string Value2 { get; set; }
}
public class RoslynTest
{
public void Test()
{
var myHostObject = new MyHostObject
{
Value1 = "Testing Value 1",
Value2 = "This is Value 2"
};
var engine = new ScriptEngine();
var session = engine.CreateSession(myHostObject);
session.AddReference(myHostObject.GetType().Assembly.Location);
session.AddReference("System");
session.AddReference("System.Core");
session.ImportNamespace("System");
// "Execute" our method so we can call it.
session.Execute("public string UpdateHostObject() { Value1 = \"V1\"; Value2 = \"V2\"; return Value1 + Value2;}");
var s = session.Execute<string>("UpdateHostObject()");
//s will return "V1V2" and your instance of myHostObject was also changed.
}
}
No. You can not.
At least in any simple way.
The thing you want is something like eval('do something') from javascript.
That's not possible to do with C#. C# is a language which needs compilation before execution unlike javascript (for instance).
The only way to implement that is to build your own (pretty complicated as for beginner) parser and execute it in such way.
UPDATED:
Actually, as JDB fairly noticed, that's really not the only way. I love programming! There are so many ways to make a freakky (or even sometimes that really can be necessary for some custom interesting tasks (or even learning)!) code. he he
Another approach I've got in my mind is building some .cs file, then compiling it on-the-fly and working with it as some assembly or some other module. Right.
My senior project is building a reservation system in ASP.NET/C#. Part of my senior project is to have c# classes (and basically use everything ive learned in the past few years). One thing Im trying to do is after I instantiate a new "user" class I need it to travel between the pages. I know session states holds variables, so I figured a session state would work where I can simply type "Session["blah"]." and have access to its members. But I dont see that happening. I realize session states are HTTP context, so i doubted it would work anyway. But is there any other way in which I can accomplish what I need without instantiating a new user class every time? I know its a webpage...but im also trying to make it as much as a functional online program as I can.
Just for coder's sake, heres the code snippet im working with:
cDatabaseManager cDM = new cDatabaseManager();
string forDBPass = Encryptdata(pass_txt.Text.ToString());
string fullName = fname_txt.Text.ToString() + " " + lname_txt.Text.ToString();
cDM.regStudent(email_txt.Text.ToString(), forDBPass, fullName, num_txt.Text.ToString(), carrier_ddl.SelectedValue.ToString(), this);
//ADD - getting a cStudent
cUser studentUser = new cStudent(fullName, forDBPass, email_txt.Text.ToString());
//ADD - session states
Session["cStudent"] = studentUser;
//Session["cStudent"]. //session state will not work with what I am doing
//ADD - transfer to campus diagram
Thanks in advance!!
EDIT:
I want to thank all of you who posted and commented! Ive learned alot from this short discussion. All your answers helped me understand!
From your comment:
The issue is when I type "Session["cStudent"]." I don't have access to my functions. Example: Session["cStudent"].getName() does not give my functionality.
This is because the [] indexer for Session sets/returns objects. The compiler does not know that you stored a cUser object and so you can't access the properties directly without a cast:
string name = ((cUser)Session["cStudent"]).getName();
There are two things that could go wrong here:
If Session["cStudent"] is null you will get a NullReferenceException
If Session["cStudent"] is not really a cUser you will get an InvalidCastException
You should check these conditions and react appropriately if one of them is true.
Also, as others have pointed out, the cUser class needs to be marked as Serializable in order to be stored in Session state.
Session stores item as objects. As long as your class inherits from Object (which it does) you can store it there. Quick caveat, it stores that object using Serialization, so your class must be serializable.
Add a property to your class like so:
public cStudent CurrentStudent
{
get {
if(Session["CurrentUser"] == null)
return null;
return (cStudent)Session["CurrentUser"];
}
set {
Session["CurrentUser"] = value;
}
}
When retrieving an object value from session state cast it to appropriate type.
[Serializable]
public class student
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
In Page1:
student s1 = new student();
s1.FirstName ="James";
s1.LastName = "Bond";
Session["blah"] = s1;
And when you want to access Session["blah"] in page 2
student s2 = (Session["blah"] !=null ? (student)Session["blah"] : null);
Now you can access properties of s2 as s2.FirstName, s2.LastName
I have an interface that looks like this...
public interface ITempFileNameBuilder
{
string DirectoryPath { get; }
string FileName { get; }
void GenerateNewFileName();
}
... and I want to mock the GenerateNewFileName method so that it sets the FileName property to something new. I know this is an odd request because obviously there is no set defined in the interface because it's declared as private set; in the two implementations. I did that so you must call GenerateNewFileName to set the FileName property to something new.
Is this possible?
Edit
Here is the unit of work I'm trying to test.
public void StartRecording(string claimNo, string ip_no, string ip_name, IWaveIn input, Stream writer)
{
if (this.IsRecording)
{
return;
}
if (_input != null)
{
_input.Dispose();
}
_input = input;
_input.WaveFormat = _waveFormat;
_input.DataAvailable += (s, args) =>
{
_writer.Write(args.Buffer, 0, args.BytesRecorded);
byte[] buffer = args.Buffer;
for (int index = 0; index < args.BytesRecorded; index += 2)
{
short sample = (short)((buffer[index + 1] << 8) | buffer[index + 0]);
float sample32 = sample / 32768f;
_aggregator.Add(sample32);
}
OnDataAvailable(args);
};
_input.RecordingStopped += (s, args) =>
{
_input.Dispose();
_writer.Dispose();
OnRecordingStopped(args);
};
if (this.CurrentRecording != null)
{
_tempFileNameBuilder.GenerateNewFileName();
}
this.Recordings.Add(new RecordingTrack(claimNo, ip_no, ip_name,
_tempFileNameBuilder.FileName,
_recordingDeployer,
_recordingCompressor));
if (this.MicrophoneLevel == default(float))
{
this.MicrophoneLevel = .75f;
}
_aggregator.Reset();
_writer = writer;
_input.StartRecording();
this.IsRecording = true;
}
And the goal of this unit test is to ensure that the FileName of the CurrentRecording and LastRecording are in fact different. It's a regression test based on a bug we found earlier. The bug was happening because the FileName property on the RecordingTrack was not being set but rather was just returning the current FileName from the ITempFileNameBuilder instance and so the idea is to ensure that GenerateNewFileName was called and ensure that the set for the TempFileName on the recording track was called.
However, the set on the TempFileName on the RecordingTrack is private too, it's done in the constructor, so maybe this isn't really a unit test and more so an integration test?
You're mocking the interface, not the implementation. So you should care about how the caller interacts with this. If you expect them to call GenerateNewFileName() and then access FileName, just expect those two calls and give back the appropriate results (where the "generated" filename can just be anything).
There's no "field" to set here - you're just talking about an API.
Of course, you could easily create a fake instead of a mock, and use that instead.
In a case like this, you need to use an explicit private field instead of the implicitly-generated one in the property. You'll need to make sure that implementations define the get method for the FileName property in terms of that private field.
I am working on a project where I am converting some VB.Net class libraries to C# libraries (mostly to learn C# syntax). My problem is that I cannot get the Save function working.
I am building my object with this:
public static StoreEmployee Create(string LoginId)
{
var emp = new StoreEmployee();
using (var dt = DAC.ExecuteDataTable("usp_ActiveEmployeeSelect",
DAC.Parameter(CN_LoginId, LoginId)))
{
emp.StoreId = Convert.ToString(dt.Rows[0][CN_StoreId]);
emp.FirstName = Convert.ToString(dt.Rows[0][CN_FirstName]);
emp.LastName = Convert.ToString(dt.Rows[0][CN_LastName]);
emp.UserName = Convert.ToString(dt.Rows[0][CN_UserName]);
emp.Role = Convert.ToString(dt.Rows[0][CN_Role]);
emp.Description = Convert.ToString(dt.Rows[0][CN_Description]);
}
return emp;
}
And then creating it with this
private static void FillStoreEmployeeObject(string empLoginId)
{
StoreEmployee.Create(empLoginId);
}
And then trying to use this save function to save the object back to the database:
public override Boolean Save(string LoginId)
{
try
{
int retVal = DAC.ExecuteNonQuery("usp_ActiveEmployeeSave",
DAC.Parameter(CN_LoginId, LoginId),
DAC.Parameter(CN_StoreId, StoreId),
DAC.Parameter(CN_FirstName, FirstName),
DAC.Parameter(CN_UserName, UserName),
DAC.Parameter(CN_Role, Role),
DAC.Parameter(CN_Description, Description));
return true;
}
catch
{
return false;
}
}
I don't get a syntax warning for that but I have revised it many times so I want to make sure that is correct before I move on. Does this look correct? By the way I am trying to call the Save function with this
StoreEmployee.Save(Convert.ToString(Login))
which gives me this error An object reference is required for the non-static field, method, or property However when I mark my function as static my Create function shows errors so I am left very confused.
Save is an instance method.
As the error message states,you need to call it on an existing instance of StoreEmployee (such as the one returned by Create).
This is just a matter of taste but I'd like to hear some of your opinions (that's also why this question is marked as subjective).
If I have a property, say
private string _Text;
public string Text;
get
{
object tmp = ViewState["Text"];
if (tmp != null)
_Text = Convert.ToString(tmp);
return _Text;
}
set
{
ViewState.Add("Text", value);
}
Now this is the property which may be specified by the programmer, by setting some custom text. This is then mapped - say - to some control on the UI. In the default case however, the Text of the control comes from a predefined resource file. So internally to handle that internally in a better way, I'd have some central point where I check whether the user has specified the "Text" property (above) and if so, use that data, otherwise rely on the default one from the resource file.
So what approach would you take? I have two options in mind:
private string ResolvedText
{
get
{
if(!string.IsNullOrEmpty(Text))
return Text;
else
//return the one from the resource file
}
}
Or put everything in a method
public string GetResolvedText()
{
if(!string.IsNullOrEmpty(Text))
return Text;
else
//return the one from the resource file
}
The question may sound stupid to you since it's really a minor difference. But I'd like to know whether there are some conventions about this.
Thx
Personally, I'd take the body of your GetResolvedText method, and use it in the property, thus:
private string _Text;
public string Text
{
get
{
if(string.IsNullOrEmpty(_Text))
//return the one from the resource file
else
return _Text;
}
set
{
_Text = value;
}
}
This puts all the responsibility for managing the string into the one place. The class itself can access _Text internally, if it needs the raw value.
I find that the best general rule here is: if calling the action twice results in multiple resource calls or different behaviour - use a method.
So, in your example use of a property is fine if it caches:
public string ResolvedText
{
get { return Text ?? (Text = GetResolvedText()); }
}
However the method doesn't need to - users expect it to be a more intensive operation:
public string GetResolvedText()
{
//return the one from the resource file
}
The design question is how do you want this class to be used?
A property will get called as if it is a 'cheap' operation:
if( myInstance.ResolvedText != null &&
myInstance.ResolvedText.Length > 5 )
Response.Write( myInstance.ResolvedText );
A method hints to the developer that they should call it as few times as possible:
string resolvedText = myInstance.GetResolvedText();
if( resolvedText != null &&
resolvedText.Length > 5 )
Response.Write( resolvedText );
Personally I prefer to keep interim classes simple, so in the vast majority of cases I would use the method model.
As this is a fairly standard convention you should avoid properties that don't cache and methods that do.
I would keep this as a property, since it represents a single value that does not require a lot of computing to retrieve.
To me, if the getter can't throw an exception, or null/invalid value, it should be a property. It is what properties are made for.
BUT, if you do some complicated stuff, if has to be a a function getter. Obviously here you have only 1 if, so I would use a property.
Reworking together your example and Steve's answer, plus adding in some caching, as obviously the resource value should be read only once since it never changes and by contract we must return the value from the property as fast as possible:
private static string ResourceText;
static [constructor]
{
ResourceText = //get resource;
}
private string text;
public string Text;
get
{
string tmp = (string)ViewState["Text"];
if (!String.IsNullOrEmpty(tmp))
text = tmp;
else
text = ResourceText;
return text;
}
set
{
ViewState.Add("Text", value);
// Note: passing null or empty strings will not work.
}