I have a Control lblDate in User Control MainScreen. I would like to modify it in a method in class Date, which is in another project AoWLibrary. I can't reference it because AoWLibrary is a dependent of the first project.
I tried to make lblDate static but the compiler kept throwing errors at me, and I have a public property that Date can't seem to access:
public Label LabelDate
{
get { return lblDate; }
set { lblDate = value; }
}
In class Date, I need public method CalculateDate to modify the Text property of lblDate
public static void CalculateDate()
{
GameDate = month.ToString() + "/" + displayDay.ToString() + "/" + year.ToString();
// LabelDate.Text = GameDate;
// This is essentially what I need to do
}
Also, I can't even access lblDate in other controls in the same project.
So, the general idea is that you need to keep track of what is in scope. There are a lot of ways to go about doing what you want to do, but any of them rely on objects referencing each other properly in ways you may not quite understand fully yet. Don't worry-- everyone has to work through this at some point.
The reason the compiler complained when you tried to make that member static is because the label itself is not static. Being tied to a single instance of MainScreen, it has no meaning in a static context, which is by definition a scope without any inherent reference to a particular MainForm.
Your Date class is, of course, a totally different context, too, but its non-static members do have access to an instance of Date. There isn't any path between these two contexts until you create it. The static route actually would have worked (look up the Singleton pattern: the idea being that you store the first and only instance of a class statically and refer to it from elsewhere) but is probably not good design. Other ways to do this are by passing to Date an instance of MainScreen (preferably through an interface) or even LabelDate itself. All of these could get the two pieces you need together to talk.
However, I would like to suggest you think about where your game state is being stored. Is it in the library or the consuming assembly? If the former, you might want to think about creating a complete GUIless model of the data that needs to be stored and manipulated in the library class and only consume that ready-made data as-is in the main application. The other alternative is that your model lives in the main application, and just calls back to your library as necessary. In this case you should probably stick for now to asking the library for answers (or at most listening for events in the library) and NOT expecting it to reach back to the application on its own (whether to get or provide information).
In figuring out how to do this you will probably find your scope management issues are much easier to handle. Even a little bit of good architecture can go a long way.
But if this is all a little overwhelming, don't stress it too much. It sounds like you are doing this for fun, which is a great way to learn. You'll come up against issues like this and will either hit on a good design or a not-so-good one, but either way you're wrestling with important concepts and will come away better for it.
the propertie LabelDate is from the class of your userControl MainScreen, but you're not instatiating any userControl.. Which instance of MainScreen do you expect to modify then?
you should do
this.controlMainScreen.LabelDate = GameDate;
considering that you say in your comments, that you have
FormMain.Designer.cs there is: this.controlMainScreen = new Adventurers_of_Wintercrest.UserControls.MainScreen();
I'd rather advise you make your GameDate method to return a string then call it from your main project which are essentially what libraries are meant for. e.g.:
public static string CalculateDate()
{
return month.ToString() + "/" + displayDay.ToString() + "/" + year.ToString();
}
//in your main project
LabelDate.Text = myLibrary.CalculateDate();
For accessing it from other controls in the same project, you should use a delegate - Provide a delegate which performs the addition, declare the delegate and invoke the function from your CaculateDate. Example:
public delegate void dateSet(string);
public void setDate(string date)
{
labelDate.Text = date;
}
then in your CaculateDate method:
labeldate.Invoke(new MainForm.dateSet(), GameDate);
Related
I've built a reusable Class Library to encapsulate my Authentication logic. I want to be able to reuse the compiled *.dll across multiple projects.
What I've got works. But, something about how I'm making the reference, or how my Class Library is structured isn't quite right. And I need your help to figure out what I'm doing-wrong/not-understanding...
I've got a Class Library (Authentication.dll) which is structured like this:
namespace AUTHENTICATION
{
public static class authentication
{
public static Boolean Authenticate(long UserID, long AppID) {...}
//...More Static Methods...//
}
}
In my dependent project I've added a reference to Authentication.dll, and I've added a using directive...
using AUTHENTICATION;
With this structure I can call my Authenticate method, from my dependent project, like so...
authentication.Authenticate(1,1)
I'd like to be able to not have to include that "authentication." before all calls to methods from this Class Library. Is that possible? If so, what changes do I need to make to my Class Library, or how I'm implementing it in my dependent project?
In C# a function cannot exist without a class. So you always need to define something for it, being a class for a static method or an object for an object method.
The only option to achieve that would be to declare a base class in the Authentication assembly from which you inherit in the dependent projects.
You could expose Authenticate as a protected method (or public works too), and call it without specifying the class name.
public class MyClassInDependentProject : authentication
{
public void DoSomething(int userId, long appId)
{
var success = Authenticate(userId, appId);
…
}
}
That said, you'll quickly find this to be a bad design. It conflates a cross-cutting concern with all sorts of other classes, and those classes are now precluded from inheriting from any other class.
Composition is a core principle of object-oriented programming, and we have the idiom "Favor composition over inheritance." This simply means that we break down complexity into manageable chunks (classes, which become instantiated as objects), and then compose those objects together to handle complex processing. So, you have encapsulated some aspect of authentication in your class, and you provide that to other classes compositionally so they can use it for authentication. Thinking about it as an object with which you can do something helps, conceptually.
As an analogy, think about needing to drill a hole in the top of your desk. You bring a drill (object) into your office (class). At that point, it wouldn't make sense to simply say "On," because "On" could be handled by your fan, your lamp, your PC, etc. (other objects in your class). You need to specify, "Drill On."
If you are making a class library in C# you should learn to use the naming conventions that exists: Design Guidelines for Developing Class Libraries
Here is how you should name namespaces: https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/interface
C# is also an object oriented language, hence the need of classes (using Authentication as you should name your class).
It also seems like the data source is hard coded. Your class library users (even if it's just you) might want to configure the data source.
Google about singleton and why it's considered to be an anti pattern today (in most cases).
You are obliged to use Class in order to invoke your method, just
When is static class just NameClass.Method
When is not static, you must create instance, ClassName ob = new ClassName(); ob.Method();
The format of a call like this is class.method, and you really can't escape using the "class" moniker even with the "using" designation. Something has to "host" the function.
I don't think what you are asking for is possible without using the base class method Jay mentioned. If all you want is to simplify the syntax whenever you call Authenticate() however, this silly solution (adding an extra method in each class that needs to do authentication) may be just what you want:
private static void DoAuth(long UserID, long AppID){
authentication.Authenticate(UserID, AppID)
}
If the ID's are always the same within some context, you could also overload it:
private static void DoAuth(){
DoAuth(1,1)
}
Yes, this does mean you have to add more code wherever you want to do the authentication (that's why it's silly! ;) ). It does also however, also reduce this:
authentication.Authenticate(1,1);
...into this:
DoAuth();
I leave the cost / benefit analysis of this up to you..
I know I am some 3 years late but here goes nothing.
To keep your code cleaner and more readable you should create a new namespace for all the re-usable code that you want to have. Then in that namespace have the Authentication Class and Authenticate Function.
To use this you can easily set a using on your namespace and use the function as you are doing like
Authentication.Authenticate()
But to use
Authenticate()
by itself you can always do
using MyNamespace.Authentication;
and in your code use Authenticate Function directly.
I'm using
Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + "\MyProgram"
As the path to store several files used by my program. I'd like to avoid pasting the same snippet of code all over the my applcation.
I need to ensure that:
The path cannot be accidentally changed once its been set
The classes that need it have access to it.
I've considered:
Making it a singleton
Using constructor dependency injection
Using property dependency injection
Using AOP to create the path where its needed.
Each has pros and cons.
The singleton is everyone's favorite whipping boy. I'm not opposed to using one but there are valid reasons to avoid it if possible.
I'm already heavily using constructor injection through Castle Windsor. But this is a path string and Windsor doesn't handle system type dependencies very gracefully. I could always wrap it in a class but that seems like overkill for something as simple as a passing around a string value. In any case this route would add yet another constructor argument to each class where it is used.
The problem I see with property injection in this case is that there is a large amount of indirection from the where the value is set to where it is needed. I would need a very long line of middlemen to reach all the places where its used.
AOP looks promising and I'm planning on using AOP for logging anyway so this at least sounds like a simple solution.
Is there any other options I haven't considered? Am I off base with my evaluation of the options I have considered?
I've never seen a problem with creating a static class like Environment for my own projects, when there's been strong enough need.
MyAppEnvironment.ApplicationFolder
If you're passing the value in using injection then you're either a) creating a class just to hold the value or b) passing in a string. The latter is bad, because your value should be constant. The former is valid, but seems like a fair overhead since there's only ever a single valid value (and you can still mock/fake that value for tests if you really need to).
I suppose you could inject your environment class, but for me this seems like overkill.
It seems like what you have amounts to a global setting within your application. Using AOP o constructor injection to pass around this dependency seems like quite a bit of overkill since a simpler solution would do the trick.
My preference here would be to use a static property on a static class. I would add a specific write routine that prevents multiple sets. For example ...
public static class GlobalSettings {
private static string s_path;
public static string Path { get { return s_path; } }
public static void UpdatePath(string path) {
if ( s_path != null || path == null ) { throw ... }
s_path = path;
}
}
We would constructor inject a class of type IMyAppConfig which is just a wrapper for all this kind of stuff.
if you have a standard .net application, you should already have a settings - class. you could create a new setting and set that value as default value or so.
My process is to always ask questions like these: What kinds of things can change? What would create the least amount of pain when those things change? What pieces can be re-used in other systems, and how can the pain of the reuse be minimized? Basically, how can these things be decoupled as much as possible?
With that in mind, the answer is really based on the details of the system that you are working on.
In whatever process uses this path, I would likely pass it down as a parameter. This would start at whatever action initiates the use of the path. Each method should "do one thing well", and if the path is part of that thing, then it should be a parameter. In the class that initiates the action (and in whatever classes control the lifetime of that class, etc.), I would likely make the path part of the constructor.
This is the method that I have used in the past, and it has served me well. For example, in one application I took this approach, and then later discovered a need to allow the user to change the path setting. By following this architecture (and avoiding a singleton) the objects that had already used the path could continue to use the old one without an error, but the new path was used correctly from the point of the change. It just worked.
And the classes can be migrated to a new project without a dependency on this particular detail.
In Visual Studio 2008 Team System, I just ran Code Analysis (from the Analyze menu) on one of my C# projects. One of the warnings produced was the following:
Microsoft.Design : Because field 'Connection._domain' is visible outside of its declaring type, change its accessibility to private and add a property, with the same accessibility as the field has currently, to provide access to it.
It's referring to the following field:
public abstract class Connection
{
protected string _domain;
}
I don't understand the reasoning behind the suggestion. This is what I think it wants me to do:
public abstract class Connection
{
private string _domain;
protected string Domain { get { return _domain; } set { _domain = value; } }
}
Two questions:
Did I understand correctly what the suggestion wants me to do, code-wise?
Why does it want me to do this?
Yes, I think you understood correctly - although in later versions of C#, there's a more concise way to write it:
public string Domain { get; set; }
Why? It's all about encapsulation. If you do as it suggests, you can later change the definition of the Domain property without affecting any calling code that uses that property. Since your class is public, and might conceivably be called by code that you didn't write, that's potentially quite important.
This is because if you ever wanted to change the field to a property in the future you would break any other assemblies that depend on it.
It is good practice to keep all fields private and wrap them in properties so that you have the option of adding validation or other logic in the future without recompiling all consumers (or in this case inheritors) of your class.
Yep. That's the suggestion. You shouldn't have any accessibility higher than private exposed as direct instance fields.
It's one of the main principles of OOD - encapsulation also referred to as 'data-hiding'.
Yes, you did correct the problem code wise.
It is about encapsulation. _domain is data about your object. Rather then exposing it directly so that any client has unfiltered access, you should provide an interface for them to access it. Practically this might be adding validation to the setter so that it can't be set to any value. It might seem silly if you are the only one writing code because you know how your API works. But try to think about things on a large enterprise level, it is better to have an API so that your object can be seen as a box that accomiplishes a task. You might say you will never have the need to add something like validation to that object, but things are done that way to hold for the possibility of it, and also to be consistent.
Your translation is correct. The same argument for can be made for using 'protected' properties as can be made for using 'public' properties instead of exposing member variables directly.
If this just leads to a proliferation of simple getters and setters then I think the damage to code readablity outweighs the benefit of being able to change the code in the future. With the development of compiler-generated properties in C# this isn't quite so bad, just use:
protected string Domain { get; set; }
In answer to your question... yes.
However, I would just use the auto-property syntax:
public abstract class Connection
{
protected string Domain { get; set; }
}
Basically, properties provide more than returning or setting a member. They allow you to add logic that could verify a proper input format, range validation, etc.
The selected answer from the link puts it best, "Properties provide encapsulation. You can encapulate any needed validation/formating/conversion in the code for the property. This would be difficult to do for fields."
http://social.msdn.microsoft.com/Forums/en-IE/netfxbcl/thread/985f4887-92ae-4ec2-b7ae-ec8cc6eb3a42
In addition to the other answers mentioned here, public/protected members that begin with an underscore are not CLS-compliant, in that there is no requirement for .NET languages to support members with leading underscores, so someone inheriting from your class in a different .NET language may not be able to access that particular protected member.
I know, it probably doesn't apply to you, but it might be part of the reason for the code analysis warning.
I am trying to structure my code in such a way to reduce/avoid code duplication and I have encountered an interesting problem. Every time my code invokes a stored proc, I need to pass few variables that are common to the stored proc: such as username, domain, server_ip and client_ip. These all come from either HttpRequest object or a system.environment object.
Since these are passed to every stored proc, my initial thought was to create a utility class that is a database wrapper and will initialize and pass these every time, so I don't have to do it in my code.
The problem is though that c# class (inside App_Code folder) doesn't see Httprequest object. Of course, I could pass this as an argument to the wrapper, but that would defeat the whole purpose of creating the wrapper. Am I missing something here?
I realize it's not such a huge deal to repeat 4 lines of code each time I call a stored proc, but I would rather eliminate the code duplication at the very early stages.
Set up your data layer to inherit from a base class which contains 4 properties for those values. Make the public constructor require those 4 properties.
Then do something similar in the business layer - base class with those 4 properties in the constructor.
Then the UI does new BusObj( Request["username"], ... ).method()
Within the data layer you can have a method that builds a SQLParameter array with those 4 properties, then each method can add additional parameters to the array.
As a general rule regardless of programming language, if you can squint your eyes and the code looks the same you should make a function/method/message out of it and pass the parameters.
Another thing to look at once you have methods that take a large number of parameters (4 is a good rule of thumb, but it is definatly a case-by-case basis) it is time to make that method take an object as a parameter instead of individual parameters. 99.99999999999999999999% of the time such an object should be immutable (no writeable instance variables).
HttpContext.Current has similar information to what you find in HttpRequest and more importantly is available inside App_Code.
Here's a weird idea you may or may not like: define a 'profile' class and a function that expands the profile into the arguments of functions taking the common arguments.
class P {
readonly string name;
readonly string domain;
public P(string name, string domain) {
this.name = name; this.domain = domain;
}
public void inject(Action<string, string> f) {
f(p.arg1, p.arg2);
}
public T inject<T>(Func<string, string, T> f) {
return f(p.arg1, p.arg2);
}
}
It might work better in VB.net where you have the AddressOf operator. I would be really cautious using this type of thing, because you could easily damage readability and encapsulation.
I would keep it the way you have it now. It's cleaner, easier to extend/modify, and easier to unit test.
As for using HttpContext instead as some others have suggested, I would say that it is a bad idea. Once you start introduce dependencies in your domain on HttpContext, it's very difficult to take it out. What if later on you wanted to use your module without an HttpContext? What about unit testing it?
Try System.Web.HttpContext.Current.Request to get the current request.
You are possibly headed down a slippery slope. The point to DRY is to not repeat business logic in multiple places where a change in requirement creates the need to change code in multiple similar places. You don't necessarily refactor just because 4 lines are the same if those 4 lines are context dependent. You have also broken encapsulation by referencing the httprequest in that you are using a global variable. As a consumer of you class I would have to know the implementation detail that I could only call you from a web application.
That being said, if you take that into account and still want to proceed, here is another option for information like this. Create a custom SecurityPrincipal (Implement IPrincipal) that contains the properties you need and attach it to the thread. Fill them when the user logs in and then you can access it anywhere during the request. Your caller would still need to make sure this was done but at least it isn't platform specific.
Otherwise for the best encapsulation, pass in a class with the properties you need into the constructor for each object that needs to consume those properties.
I have an initialization class that preloads content into a variable (probably a list or array). There will only be one instance of this initialization class but there will be many classes that need to access the preloaded content.
The problem is not many of them are related and none of them extend my initialization class. I thought about this for a bit and decided on using a static method and variable for this use. So something like this...
public class InitClass
{
static List PreloadedContent;
static ModelData GetContent(String ContentName)
{
//return the preloaded content that matches given name
}
}
The preloaded content may at some time decrease or increase in size depending on what the situation may call for. I've run into situations where something like this has been the only decent looking solution however; I think its an ugly solution.
Note: I can't load the data onto a class that needs it when it is created due to a variety of reasons - most of which are reasons I don't know about yet but will most likely come up. Certain classes will be loaded/unloaded depending on the rendering of the scene and my InitClass won't handle the creation of these objects most of the time.
Can anyone give me a better solution?
what you are doing is known as singleton. here are some previous discussions on this:
How to implement a singleton in C#
What’s a good threadsafe singleton generic template pattern in C#
To avoid static/global scope you could use some kind of Registry class. This means you have one class which you initialize at program startup. This class holds references to all other classes that need to be accessed globally.
Now you pass the initialized instance of your registry class to all instances in your application.
It isn't a very pretty soluation, but for me it is the best. With Static and global variables I always ended up in having some problems when testing or debugging code.
Another aproach would be to use a Singleton. Since they also just hold a static instance I would not prefer them.