Basically, I'm passing a model object to a method and in that method, assigning the proper object from the database. Since this is a reference, I assumed it would persist throughout the rest of the method in which it it was called/passed. I know this has something to do with the proxy of entity framework but can't figure out how to fix it. Here is a fragment of the code:
[HttpPost]
public ActionResult Create(NewFormViewModel nfvm)
{
db = new dbconnection(connStr);
Track track= new Track();
Track parentTrack = new Track();
this.Create_SetTrack(nfvm, track, parentTrack);
...
and then in Create_SetTrack:
private void Create_SetTrack(NewFormViewModel nfvm, Track track, Track parentTrack)
{
track = db.Tracks.FirstOrDefault();
parentTrack = db.Tracks.Where(i=>i.ParentID==track.ID).FirstOrDefault();
}
The track loads in Create_SetTrack but then, after the code after the '...' continues in Create, track is back to it's null values.
Note that a method parameter is a new variable. So you assign track (the variable) to track (the parameter). In the method body, the parameter is overwritten by a new reference, but the original track (the variable) has nothing to do with that.
You are probably confused by the fact that changes you make to the same reference object will be visible outside the method body. If you'd only set a property of a new Track() object, you'd see this value after the Create_SetTrack call.
So I would make a method that returns the tracks, so you can assign then to the original variables. If this is an internal method, you could return a Tuple (using Tuples in API methods is discouraged, because the ItemX properties are too nondescript).
As an alternative, you could assign the tracks to another object (the view model?) that is not overwritten in the method body.
I'd prefer the first alternative though. I don't like methods that create side-effects.
That won't work unless you use a ref parameter. Otherwise, the track parameter reference will only exist in the scope of the method
private void Create_SetTrack(NewFormViewModel nfvm, ref Track track)
{
track = db.Tracks.FirstOrDefault();
}
I would advise against this, though, since it makes the code more complicated that it needs to be. A better solution is to simply return a value from the method and assign that to your variable:
private Track Create_SetTrack(NewFormViewModel nfvm)
{
return db.Tracks.FirstOrDefault();
}
[HttpPost]
public ActionResult Create(NewFormViewModel nfvm)
{
db = new dbconnection(connStr);
Track track= Create_SetTrack(nfvm);
....
Related
I have a function that returns a Dictionary<uint, SomeClass> this function is called every second updating data to my list.
Right now, used like this to update my property:
MyData = Api.GetData();
And my property as:
public static Dictionary<uint, SomeClass> MyData { get; private set; }
Is that method fine to update my Dictionary or how should it be done?
I mean, the Dictionary is constantly being replaced as it is right now, right? So if I am using or updating any entry of that Dictionary say:
MyData[SomeValidKey].SomeProperty
My reference would become null or invalid? Or it would simple use a copy of it? Or this is something that would only have a chance to ever happen depending on how fast MyData is queried and the such?
What would be an optimal way to update my Dictionary, while allowing other parts of my application to freely access and use it?
The dictionary is mainly read only and/or call functions of a given item in the Dictionary that is part SomeClass.
UPDATE:
Since MyData = Api.GetData(); means the list is actually replaced? If so if an entry that previously existed no longer exist but any of my functions still had it in use, it would cause exceptions? If an item that was previously used is updated I would not have the updated data as my reference is dead?
So the way I am updating my Dictionary is clearly wrong?
If you're updating your Dictionary in a separate thread then you should use proper locking mechanism to ensure that you're reading the current value. Use lock for both read/write. Also there is a ConcurrentDictionary class in .NET 4 (or above) which is designed for concurrent operations.
But if you're using your dictionary in a single thread then you shouldn't worry about locking at all. Here is an example to demonstrate what happens when you change the reference to another someClass instance:
private class SomeClass
{
public string Name { get; set; }
}
...
Dictionary<uint, SomeClass> dic = new Dictionary<uint, SomeClass>
{
{ 1u, new SomeClass { Name = "1"}},
{ 2u, new SomeClass { Name = "2"}}
};
var sc1 = dic[1]; // sc1 refers to old instance of SomeClass
dic[1] = new SomeClass { Name = "new" }; // now we change the reference here
string oldName = sc1.Name; // oldName is still "1", because sc1 points to the old instance
Your question is different to your example. Your example states you are replacing your dictionary when you call your API. Your question corresponds to updating.
If you were to update your dictionary, then you can either assign the return of your Api call to a temporary dictionary, then transfer/add/delete values in MyData or pass MyData to your Api function and handle that functionality there. This would keep your references in tact if accessed from other parts of your application.
If this isn't possible, then you cannot guarantee that there aren't to be errors from other parts of your code when you replace your MyData object with your Api call. The easiest solution here would that you do not cache your MyData entry value but instead cache its key. Other parts of your application can then check if their cached key is valid and take appropriate action.
I have a controller like this:
public class LoginController : Controller
{
private Int32 _companyID;
// My actions
}
This variable _companyID should (obviously) contain the id of the company, and this value is currently on the session. I want to get that value and set on the controller variable.
Edit: I'm using this variable because I have to check some things about this value from the session and I don't want to duplicate this code in every action. Instead, I just want to check what I need, set this value in the variable and use it inside my actions.
On WebForms, I'd simply get the value from the session in the page load event and it'd be done. But in MVC, I don't know how I do that.
My first thought was get this value in the constructor, something like that:
public LoginController()
{
_companyID = Convert.toInt32(Session["companyID"]);
}
But I discovered that session can't be accessed on constructors (it was null for me).
Then I thought about using filters, but I wasn't able to figure out how I set the value in the controller variable. I've tried in this way:
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
Int32 _companyID = Convert.toInt32(HttpContext.Current.Session["idEmpresa"]);
// I couldn't pass this value directly to the controller variable
}
I've seen a few ways to pass values from filters to controllers, but all of them imply in extra code in my actions to get that value from the filter, and I don't want that. I'd like a way that I can get the desired value without change every action that I have or will have.
Is there a way to get that?
I hope that my question is clear enough. Thanks in advance!
First, the variable is not global, it's an instance variable on the controller. A bit pedantic, yes, but those are entirely different things.
Second, there's no point to setting an ivar on the controller with the value from the session, anyways, because the controller is instantiated and disposed with each request. In other words, this is never shared between actions, regardless; each time you call a new action, it has to re-set the ivar.
Finally, while you could use a filter, it's unnecessary because of the last point. If you need the session variable in your controller action, just access it directly from that action. If you need to pass it to the view, you can set it in ViewBag or on a view model.
I'm using .NET C# for a project.
I have a list of products which I want to cache as they're used company wide. If the products drop out of cache I already know how to lock the cache and rebuild it ok as per the patterns on various authority/blog sites.
In my pages/user controls etc, I might grab a reference to the cache, like this:
var myCacheInstance = cachedProducts
However, I might also want to do something like this:
myCacheInstance.Add(new product(...));
Which will also update the cache as it's the same object.
I have 2 queries.
If I have a reference to the cached object is it guaranteed to remain in cache for the lifetime of my variable?
In the scanario outlined above, how do I go about ensuring integrity? I'm only planning on adding in this instance, but suppose, I was updating and deleting objects as well?
1) If I have a reference to the cached object is it guaranteed to
remain in cache for the lifetime of my variable?
If I right interpret this question: responce is no.
cache.Add("key", new object()); // ADD KEY
var obj = cache["key"]; // GET REFERENCE TO CACHED OBJECT
cache.Remove("key"); // REMOVE OBJECT FROM CACHE
obj.DoSomething(..); //PERFECTLY VALID, STILL WORK ..
2) In the scanario outlined above, how do I go about ensuring
integrity? I'm only planning on adding in this instance, but suppose,
I was updating and deleting objects as well?
Can add bool property like, for example:
public bool IsValid
{
get; private set;
}
when object removed this property is set from the class to false. Just example, iff it really fits your need can tell us only you.
Do not pass around a reference to your cache!
Use an object for your cache and if a clients wants to have the cached items return a new list of your cached items, or a readonly collection.
If you want to add items to the cache, use a method on the cache object and in that method lock the cache and add the item. Same with remove.
question 1: If you pass around references you can not guarantee anything.
question 2: Use an object to cache all your items as I described above.
public class Cache
{
private List<Item> cachedItems = new List<Item>();
public void Add(Item item)
{
lock(cachedItems)
{
cachedItems.Add(item);
}
}
}
hello in order to ensure integrity, you must add key
Cache.Add("YourKey", yourValue)
here you can find helper for all operations
http://johnnycoder.com/blog/2008/12/10/c-cache-helper-class/
For duration or timeout you have this format, where you specify absoluteExpiration
public Object Add (string key, Object value, CacheDependency dependencies,
DateTime absoluteExpiration, TimeSpan slidingExpiration, CacheItemPriority
priority, CacheItemRemovedCallback onRemoveCallback)
What is the best way of initializing objects for properties without setters in C#?
For example I have property of type UserData and I can initialize it:
In constructor
In getter
private UserData _user;
public UserData User
{
get
{
return _user?? (_user= new UserData ());
}
}
Initialize field:
private UserData _user = new UserData()
I found few similiar threads:
Create an object in the constructor or at top of the class
C# member variable initialization; best practice?
But it is consideration between 1st and 3rd option - no one thinks about 2nd option - do you know way? From some time it is my preffered option to get objects, but I wonder if there are some cons that I don't know.
Could you tell me what is the best option and what problem could make use of 2nd option?
It all depends on what you want to do with it, so there is definite answer for that.
One difference between 1+3 and 2 is predictability.
With 1+3, you know exactly where your object is created and at which point during instantiation of your class. That can be desirable in some circumstances.
With 2, you depend on external influences (who accesses the property at which time) to initialize the field.
With the delayed creation in approach 2 (only create the object if needed), you could save some time when creating an object of the containing class.
If the UserData's creation takes a lot of time, like, when you have to query a database for it, you might want to delay its creation until really necessary. The object that contains the UserData object is constructed faster since it doesn't need to wait for the UserData object to be created. If the property isn't always accessed, you might even get to completely avoid creating a UserData instance.
If you're simply using plain data, initializing the backing field at its definition (if possible) is preferred:
// when you create constructor N+1, no worries about forgetting to set the value
private UserData _userData = new UserData();
public UserData User
{
get { return _userData; }
}
If you need initialization to be deferred, your best option is using Lazy<T>:
private Lazy<UserData> _userData = new Lazy<UserData>(() => new UserData());
public UserData User
{
get { return _userData.Value; }
}
The constructor for Lazy<T> contains overloads which can address your thread safety needs:
None: access from multiple threads is "undefined behavior"
PublicationOnly: the first thread to complete initialization "wins"
ExecutionAndPublication: locks ensure only one thread initializes the value
One issue with #2 is if the property could be accessed by multiple threads you could potentially create two copies of the UserData object. An additional consideration with #2 is if UserData is expensive to create you will be paying the cost of creating that object when the property is accessed rather than when the containing object is created. That may or may not be desirable depending on your use case.
I've got an ASP.Net project that uses session state, I'd like to be a little more strict about how we access session state, I'm not happy about all the strings floating around the code. I also need to know when a particular value is stored/updated in session state for tracking that object's latest value.
The string issue is easy to solve using constants, but it doesn't help with the tracking. Encapsulating them all in a single class is appealing, but then I have to pass the session object to that class, and that seems a little messy
I'm thinking of using one of two options:
Extension getters and setters on the session object
An extension method on the session object to return a class with the getters and setters
The first gives me the syntax:
var thing = Session.GetThing();
Session.SetThing(thing);
The second gives:
var thing = Session.Wrapper().Thing;
Session.Wrapper().Thing = thing;
Both have their appeal, though I'm leaning towards the second. In an ideal world I'd like to be able to do this:
var thing = Session.Thing(); // easy to do
Session.Thing() = thing; // don't think it's possible
What's the preferred way of handling this? Any of these, another way, or am I just doing it wrong?
You don't have to pass the Session to each class, you can have:
public class State
{
public string Something
{
get { return HttpContext.Current.Session["Something"] as string; }
set { HttpContext.Current.Session["Something"] = value; }
}
}
This, I believe, is the typical approach. HttpContext has the Current property which is statically available.
My preferred method is to put all of the variables that need access into an object. Then I put a variable in our page's base class that provides the appropriate access to the object in the session. The only manner of true enforcement of this is to provide a standard that requires usage of this object and then code/peer review to ensure that miscellaneous strings/variables don't end up clogging the session up.