|
PhonyMcRingRing posted:Anyone know of a good library for converting data to Excel 2003 format without needing the interop stuff? I'm trying out ExcelLibrary right now. It works alright, but I'm not happy about having to fix glaring bugs that were reported 2+ years ago(like there being no support for DBNull values, it just throws an exception). I've only used ExcelLibrary, and that only for some very simple exporting, so I can't give you a personal description of how good this is or if it will fit your requirements, but some googling ld me to NPOI. Might be worth taking a look at, anyway.
|
# ¿ Apr 20, 2011 00:12 |
|
|
# ¿ Apr 28, 2024 20:41 |
|
UberJumper posted:I am trying to understand how to do databinding properly. I just don't quite understand how to relate my custom object, with the datasource: Edit: Read the tutorial that Sprawl linked. It's much more concise than my almanac of links and it talks about INotifyPropertyChanged, which is something I didn't know about and didn't find when looking this stuff up to answer your question. My original answer follows: There seems to be a whole mess of ways to do this, but essentially the DataSource property has to be set to an object that supports the data-binding model. MSDN has a detailed page about the DataSource property that you should look at, it tells you exactly what you can get away with. Specifically, you might want to look at adding your data members to a BindingSource, which itself can be set to the DataSource property in your DataGridView. You can also try purusing this set of how-tos, specifically the one about binding objects to DataGridView controls. I hope that points you in the right direction. I'm sorry I can't give you code for your specific problem; I've only ever made use of the DataGridView to display data populated by sql query results (via DataTables), never used the control to add data back in. Good luck. Che Delilas fucked around with this message at 09:16 on May 28, 2011 |
# ¿ May 28, 2011 09:10 |
|
IMJack posted:I inherited an old VC# '07 project and updated it to VC# '10. It's supposed to connect to an HP Quality Center instance and do work on it. To do this, it uses an interop library called TDAPIOLELib that comes with the HP Connectivity Add-in package, so anyone who installs it has to download and install the add-in first. Well, I have no experience with the HP QC or this error in particular, so consider this a lmgtfy answer. It looks like it applies to you though, so good luck. http://forums.sdn.sap.com/thread.jspa?threadID=1828572&tstart=0 quote:The communiction problem was relolved by installing QC patch 16 on server side (TD4QC_00145)
|
# ¿ Jun 13, 2011 08:49 |
|
rolleyes posted:Me and my text file pattern finding are back again. I'm pretty sure it's preferable to use a bit of system memory rather than reading back and forth in a file, so I think you're on the right track. Is there some other reason you need to know the positional information (column, line number)? If not, you could just do your checking incrementally as you read a block, kind of like this (I'm assuming that "labels" can be anywhere either before or after "label references"): code:
HashSet is a data structure that only allows unique items. Available in .Net Framework 3.5 and up. Che Delilas fucked around with this message at 22:19 on Sep 20, 2011 |
# ¿ Sep 20, 2011 22:15 |
|
rolleyes posted:Thanks, that's an approach I should really have considered. Ah yeah. Then I would suggest using a HashSet for labels (because you only need to know THAT they exist somewhere in the block, unless you want the program to warn about duplicate labels too ) and a List of structs for your label references, where the struct contains all the info you need like line and column number. So in pseudo: code:
vvv Welcome. Che Delilas fucked around with this message at 23:02 on Sep 20, 2011 |
# ¿ Sep 20, 2011 22:50 |
|
There goes my theory that Microsoft deliberately made the Express versions of VS buggy and inconsistent in order to get people to get the full version. (Seriously have you ever tried installing Web Developer Express 2010 on a machine that already has C++ Express 2010 and/or Visual Studio SP1 on it? loving nightmare).
|
# ¿ Sep 23, 2011 04:43 |
|
Canine Blues Arooo posted:I need an Image Map. Never used this before and I'm not sure about its performance but it might be worth trying out: ImageMap Control. Other ideas would be to have a still image (PictureBox control) that handles the Click event, whose behavior would be based on what the mouse coordinates are when clicked (this could be what that ImageMap control does, I don't know). As for the text, you could look into TextBlock, which is supposedly lighter weight and more appropriate for displaying text on its own than a label. You could also look into Graphics.DrawString, which will let you draw directly onto the canvas. It looks like that would require you to handle a Paint event(a good one to use is probably going to be the control that's displaying your big image). This is probably cheaper than a berjillion text controls.
|
# ¿ Sep 23, 2011 08:55 |
|
rolleyes posted:I'm not too hot on multi-thread debugging - how do I go about doing that? No personal experience with this, but some Google-fu leads me to understand that what happens is that a BackgroundWorker reports that it is done through an event called BackgroundWorker.RunWorkerCompleted. This event is registered on the UI message queue, and if that queue isn't being polled (because you are sleeping, waiting for the BW to complete), that event is never going to get handled and thus never set IsBusy to false. Try using the AutoResetEvent, which seems to have been created for a similar purpose. Here's some code that's probably more relevant to your current situation that MSDN's example. So basically in the main thread, instead of waiting for the BackgroundWorker to complete, you call your AutoResetEvent object's WaitOne() method (which will cause the main thread to wait without tying up the message loop) and in the BackgroundWorker's DoWork method, when the work is done you call the AutoResetEvent object's Set() method. No promises, I've never personally worked with BackgroundWorker before. Good luck. Edit: Oh, I guess that has its own pitfalls depending on what's going on in your BackgroundWorker (ie. if it's going to take a long time). Suggest reading the rest of that stackoverflow conversation to learn more about your options, but it doesn't look like there's a really elegant solution. Che Delilas fucked around with this message at 23:14 on Sep 24, 2011 |
# ¿ Sep 24, 2011 23:09 |
|
Sedro posted:Using an AutoResetEvent in place of spinning won't change anything because the BackgroundWorker raises its completion event on the UI thread (which is in a blocking wait). Moving the signal to the background thread (DoWork) will fix the problem, as you said. I agree that his example was trivial, I'm assuming he's not going into a method, starting the BackgroundWorker, immediately waiting for it to finish, and then proceeding. There would be no point to the secondary thread if that were the case. I'm assuming that in one method he's starting a BackgroundWorker that does something that takes a long time, and then letting the user continue to do poo poo until the user clicks on something that needs to make use of the calculation being performed by the BackgroundWorker, at which point he needs to wait for it to finish. But I promise you, AutoResetEvent doesn't block the message loop the way just checking for IsBusy and sleeping does. I just tried both techniques. This code will never get to the MessageBox. code:
code:
Edit: Thinking about it, this is basically the same thing as just having a bool (instead of an AutoResetEvent). Initialize it in the main thread as false, set it to true in the BackgroundWorker when it's done working, and once you need the data the BGW provides, have the main thread sleep until the bool is true. It still feels like a hack; there's got to be a "best practices" way to handle data locking and such, but damned if I know what it is. Che Delilas fucked around with this message at 02:43 on Sep 25, 2011 |
# ¿ Sep 25, 2011 02:03 |
|
Got a style/best practices question for the more experienced goons in here. I'm working on a winforms program that has one main form with a tab control with 5 tab pages. Each of these pages has a fair number of controls with plenty of event handlers to match. This has led to my main form class being quite large. So far, I have been breaking the class up into multiple files using the "Partial" keyword, with the little extra configuration I need to do after initialization in one file, and then the event handlers for each tab page in their own files. My question is, is there a better or more maintainable way to handle a large main windows form class like this? I've thought of logically grouping some of the controls into custom UserControls, but that doesn't seem like it will be much cleaner to me. I'm not having any problems with the functionality or performance, but I plan to show the code off to potential employers so I'd like to avoid anything really unreadable or stylistically frowned-upon if I can.
|
# ¿ Nov 29, 2011 19:54 |
|
Dietrich posted:Usercontrols are great for stuff like that. Orzo posted:Che, create a separate class deriving from UserControl for each of your tab pages. Great. I figured that UserControls would be a good way to handle the organizational problem, just wanted to check and see if there were any other ideas. That should be fairly quick to implement too, so I'll put that near the top of my to-do list. As for the MVC-like patterns, yeah, this project could probably stand to be a little more formal in that respect. I've already got my data access decoupled from my interface (mostly), but the "business" logic is pretty interwoven with my interface. Refactoring everything so that it employs a more recognizable design pattern will be a good exercise later on. Thanks for the advice guys.
|
# ¿ Nov 30, 2011 00:59 |
|
Orzo posted:True, but unless you're manually creating and adding the instance of the UserControl to the parent container's control collection (i.e. not using the designer), your constructor with parameters won't get used anyway, right? Yeah, I've worked with UserControls to solve other problems, so I'm fairly familiar with how the designer handles their initialization. As far as I know, you're right: if you add a user control to your form using the designer, it uses the default constructor, the end. I just do my additional configuration after the call to InitializeComponent(), and it's never caused me any issues. I do appreciate the heads up, though. It can be a pain stumbling through the quirks of an unfamiliar language or IDE.
|
# ¿ Dec 1, 2011 08:35 |
|
Girl With Huge Tits posted:Fair enough. I picked up the style at a previous employer and its just sorta stuck with me. Counterpoint: It's only really important that you have consistency, not that your conventions match someone else's. I mean, as long as you aren't working on the same codebase. Microsoft's standards are used by their people to write MSDN examples, they aren't meant to be taken as The One True C# (even though they are generally good guidelines for readable code). Though I've grown to hate underscores in variable names, myself.
|
# ¿ Jun 26, 2012 16:42 |
|
Ithaqua posted:Okay, so here's my conundrum today. I wrote some code to dump out a CSV containing some data, and also periodically truncate it based on a row and/or byte threshold. I think that you can't think of a better approach because this kind of thing is what streams are for in the first place. You could try optimizing by reading in multiple lines per iteration, processing them, and then using File.AppendAllLines to dump them to your temporary output file instead of writing them back out one at a time with WriteLine. I don't know how AppendAllLines compares to StreamWriter.WriteLine under the hood, though; it may very well just loop through the collection and write each line out one at a time the way you would do it manually.
|
# ¿ Jun 28, 2012 22:41 |
|
epalm posted:- Dumping bodies - So, in this example, did the user type the whole phrase and rely on word wrap? Because that looks like the correct output in that case. Or are you saying that they split the text up into three lines themselves? If I have this right, basically you have 2 rules with priority. 1) 32 characters per line max 2) Make it look like it does in the text box. So your only real problem case would be if the user typed in something longer than 32 characters, then hit enter, then typed in more stuff. That means you have to violate rule 2 so that you can still follow rule 1. Try something like: 1. Get the input from the box 2. Split on newline characters and populate the three strings (only populate the first if there are no newlines, ignore newlines entirely if there's too many). 3. Test the first resulting string for more than 32 characters. 4. If there are any overages, push the extra words onto the beginning of the next string. 5. Repeat 3 and 4 for the next 2 strings Make sure you set your text box's max length to 96(? not sure if newlines count against the max or not, something to test anyway) and you should be good. You may want to generate an error message if the user has more than 3 lines (3+ newline characters) and not let them continue since it won't look like what they output. You may also want to generate a preview of what the actual printout will look like, in case they do something wonky like type a >32 character line AND use newlines too.
|
# ¿ Jun 29, 2012 23:08 |
|
Ithaqua posted:Super anal style nitpicking: Ooh ooh can we have the "my style guide is the only style guide" discussion again?
|
# ¿ Aug 17, 2012 21:32 |
|
Ithaqua posted:Nope. My style guide is Microsoft's, so that's a pretty good starting point. Right, which is the style guide Microsoft uses for MSDN examples (and I assume internally?), which has nothing to do with anybody else's code base. Its guidelines do not supercede being consistent with your own code base. His method names are internally consistent (all 2 of them that we see, heh), so it's perfectly valid. For the record, I happen to use Microsoft's guidelines in my own work. Mostly because they're all written out and easily referenced, and there's nothing really wrong with them.
|
# ¿ Aug 17, 2012 21:42 |
|
wwb posted:Exactly -- internal consistency is the only thing that matters at the end of the day. My guess is that because that's how the .Net Framework names its own stuff. Which is in fact a good argument for doing it Microsoft's way, since non-trivial programs generally make extensive use of the Framework libraries. Code autocomplete tools like Intellisense are also so good now that a lot of the older naming conventions (some of which shall remain nameless) are unnecessary. And good riddance. The only names that are in camel case that I know of in Microsoft's style guide are fields, function params and locally scoped variables. That's enough, in my opinion, since if I'm calling a class's function from within another function of the same class, I don't really care if the function I'm calling is public or private.
|
# ¿ Aug 18, 2012 00:49 |
|
Ithaqua posted:Well, a lot of the time when you can use it, it is unnecessary. ReSharper flags redundant "this" keyword usage by default. I'm on the fence about it, personally. I mean, I suppose it can help you determine at a glance which variables are class members and which are local vars or params. But if you use it for that reason, you have to use it EVERY time you are referencing a class member, and it just seems like it pollutes your code for no real gain. Conversely, it becomes slightly harder to pick out the actual name of the variable; you have to look in the middle of the text rather than the beginning of it. Why type more for a dubious benefit?
|
# ¿ Aug 31, 2012 19:04 |
|
I couldn't find a better place for this question; if I missed an IDE thread or something please point it out to me and I'll post it there. Can anybody give me compelling reasons to move to VS 2012? I tried it briefly and couldn't get past the color scheme. There's no visual separation of anything, barely any color, no contrast. The dark color theme is better from a contrast perspective but light text on a dark background is harder to read and I am at enough risk of eye strain as it is. I don't want a huge feature comparison, I'm mostly looking for anecdotes. "I loved <thing> about 2012 over 2010." I can probably get used to the "minimalist" (bland and indistinct) colors but I'm going to need a good reason to put myself through that pain to get there. Edit: I should probably mention that I'm primarily developing WPF applications with .NET 4 at the moment.
|
# ¿ Sep 4, 2012 18:16 |
|
Thanks for the anecdotes on VS2012, guys. As I feared, I'm still lacking a compelling reason to move to it immediately, but it'll become more necessary in the future. Hopefully by then they will either support 3rd-party color themes or there will be a good tool to facilitate setting colors manually (I know you can do it now, there are just too many elements to hunt through).
|
# ¿ Sep 5, 2012 19:07 |
|
I have a design question about MVVM that I haven't been able to find a great answer to. What is generally the best way to organize your view models? I've seen two types of example: 1) One ViewModel per model. This allows you to explicitly expose the properties you want your view to have access to, and keeps change notification out of your model. These are both Good Things. 2) One ViewModel per View. This allows you to work with collections of model objects, but pushes your change notification onto the model. Every example I've ever read uses one of these methods, never both. If they're showing how to display detailed information about a single object, they use the first method. If they are showing you how to work with collections and display them using a DataTemplate, they use the second method. But it's likely that you are going to need to do both things with the same model. Is the best way to handle this just to use a two-level ViewModel approach? For example, if you have a Customer class, Have a CustomerViewModel that exposes the relevant properties for a single Customer, and then make, say, a MainPageViewModel class that contains an ObservableCollection of CustomerViewModel? I've never seen examples of this, so is there a good reason not to do it besides the fact that it adds complexity?
|
# ¿ Sep 7, 2012 17:05 |
|
Rooster Brooster posted:IANAE, but my understanding is that view-models exist to present info (and commands) to the view in a format that's easiest for the view to consume. The best description I've heard for view-models is "value converters on steroids". As such, it should be one view-model per view. Many times a view also is meant to provide access to on a single model, hence the 1-1-1 correspondence you see. Okay, then the follow up question: If I have a model that has a certain piece of information, and I need to display something about that information that isn't strictly that information, what do I do? Concrete example: My model is Alert. I am displaying a list of Alerts in my program. My model has StartTime in it and for each Alert I want to display the time that has elapsed since the StartTime. Do I wrap the Alert class and expose an ElapsedTime property that I update every second with a timer event, and then have my collection be an ObservableCollection<AlertWrapper>, or is there a better way to handle that?
|
# ¿ Sep 7, 2012 18:40 |
|
Ithaqua posted:I don't see why an Alert shouldn't have a computed ElapsedTime property. And how would I get change notification to fire on that so that it updated on the view every second? I'm sorry if I'm asking MVVM-101 questions here, but I'm fairly new to the pattern, teaching myself, and my knowledge on it is full of holes.
|
# ¿ Sep 7, 2012 18:54 |
|
Thanks for the replies, guys. I think I'm going to be able to rework my design a bit and clean up a good portion of the code thanks to some of the ideas you've given me. vvv I really should join that site, they've been the #1-3 google result for just about every question I've ever had and answered so many of them perfectly. Che Delilas fucked around with this message at 19:29 on Sep 7, 2012 |
# ¿ Sep 7, 2012 19:23 |
|
GrumpyDoctor posted:I'm trying to get a taskbar overlay working in WPF. It looks like it's talking about the properties pane, the place where you would assign properties to a control after you added it to the window, for example. When you're working with xaml (like, actually typing in xaml code), the properties pane will update depending on the element you have selected. "Selected" in this case means wherever the text carat is. It's not particularly fast and sometimes you have to build to get it to update, but it'll generally keep pace with wherever you are. In your case, click somewhere within the <ImageDrawing /> text in the xaml editor. The properties pane will update with the properties available for that element (which seem to only be ImageSource and Rect in this case). Click on the ellipses and it'll pop up a file dialog for you to choose your image. Click for huge. Che Delilas fucked around with this message at 22:47 on Oct 3, 2012 |
# ¿ Oct 3, 2012 22:40 |
|
User0015 posted:about data binding. I think I can help answer these. Question 1: He's not actually setting the DataContext twice here. What he's doing in the XAML is specifying d:DataContext. The key here is the "d," which is generally used to indicate design time (it's actually a namespace definition at the top of the XAML, specified as xmlns:d). Setting your design-time data context is mostly used to give Visual Studio Designer or Expression Blend a data context to work with that might be different from your live data context (because you don't want visual studio's designer tool to try and connect to a web service or something). It's useful for providing dummy data to use so you can format the visual look of your controls. In this case, he's also specifying IsDesignTimeCreatable="False" which will make a dummy object for the designer to use as the data context, without giving you any sample data. To keep it clean, basically. Bottom line: He's only specifying the actual (live) DataContext in the code behind. The d:DataContext is ignored when you actually run the program. Question 2: "Generate the templated items internally" means that program will do its level best to display the "items" in the list that it gets from its ItemsSource. What this usually means is that it's going to call each item's ToString() method and display the result as plain text in the control. Obviously with any kind of complex object this isn't going to be good enough, which is why we provide the control with a Template. The other part of your question is easier: the difference between ItemsSource and DataContext. Think of the DataContext as the starting point for all your bindings. Make it a class (this is usually the ViewModel in the MVVM pattern). A control's ItemsSource is, in contrast, a collection of data (often complex objects) that exists within the class you specified as the DataContext. So for example, the DataContext in this case is an instance of VideoLibraryViewModel, while the ItemsSource in the ListBox is a collection of Videos. The VideoLibraryViewModel has, as one of its properties, an IList<VideoViewModel> called "Videos". Videos is what the ItemsSource property binds to, and it knows where Videos is because you specified the DataContext, or starting point, as an instance of VideoLibraryViewModel, which again, has Videos as one of its properties. Question 3: quote:So SelectedItem is a property of your ListBox, and you bound it to the property SelectedVideo, and it automatically knows/expects an ObservableCollection<of some type?> SelectedItem is a property of the ListBox, and it is bound to the property SelectedVideo. SelectedItem doesn't expect a collection, it expects a single object (in this case a VideoViewModel). It knows what type the object is because the ListBox's ItemsSource is an IList<VideoViewModel>, so each item must be a single VideoViewModel. Basically what's happening here is that each time you select a different item from the list, the SelectedVideo property in your VideoLibraryViewModel gets updated because it is bound to the ListBox's SelectedItem property. Question 4 The DataType property of the DataTemplate element just tells it, "This is how we are going to display any data of this type." In this case, it's specifying how to display VideoViewModel objects. It should be noted that the DataType property as its used here isn't strictly necessary since the DataTemplate is being specified within the specific ListBox and we're not displaying VideoViewModels anywhere else in the window, only in that ListBox. Realize that DataTemplates are the blueprints for how you want to display a given object. You can make them as simple as a few TextBlocks or you can do all sorts of crazy formatting, spacing, colorization, anything you want. Think of them as a kind of miniature UserControl. In this example he only has one TextBlock and it's displaying the ID of the SelectedVideo, and nothing else about the SelectedVideo. In a more real-world application it would display the Name and Status as well, by including in the template two more TextBlocks bound to the respective properties. Che Delilas fucked around with this message at 00:17 on Nov 28, 2012 |
# ¿ Nov 28, 2012 00:14 |
|
User0015 posted:As far as the example I saw goes, what's going on between setting the DataContext to an instance of a class, and to the class itself? There's no setting the DataContext to "the class itself." You're always setting it to an instance of the class. If you do it in the code behind, code:
If you do it in the XAML (I'm assuming you're referring to this line from the example) : code:
It's just two different ways of doing the exact same thing.
|
# ¿ Nov 28, 2012 22:49 |
|
Sedro posted:I don't actually use UI designers; the design-time data context enables Resharper's XAML intellisense. Does this mean that Resharper's XAML intellisense works on markup extensions? We don't use Resharper where I work but if it has intellisense where Visual Studio does not I might just make a push to have it purchased. I hate the lack of complete intellisense more than just about anything when it comes to WPF.
|
# ¿ Nov 28, 2012 23:34 |
|
R.I.P.
|
# ¿ Dec 20, 2012 20:05 |
|
You could give the button's style a trigger, so:XML code:
This is likely not the best way to do this. I think messing with the ControlTemplate is probably how you handle something like this "better" but if all you want is a quick background color change, this suffices.
|
# ¿ Jan 3, 2013 20:24 |
|
Dietrich posted:For every request, and you'd have to put your own service factory in place to change that behavior. Wait, can't you just decorate your implementation with code:
|
# ¿ Jan 18, 2013 20:32 |
|
Munkeymon posted:You have no idea how much I'd love to make TFS require a comment like I've done to SVN at my last two jobs... Does this even work? I would imagine that developers who didn't comment their commits in the past would just put in "N/A" or "Made some changes" as their comment to satisfy the requirement without actually putting in real information. At least, that's what I'd think would happen without an accompanying policy with consequences for not following it.
|
# ¿ Feb 15, 2013 18:29 |
|
epalm posted:Anyone have any experience with .net and printing to impact printers using custom page sizes? The question is here but the gist is I have 8.5 x 8.5 paper, but no matter what I do starting from a WPF PrintDialog, the printer ejects 11 inches. Are you trying to print Controls that are on the screen, or are you just trying to print text in memory somewhere? I should mention that I do not have any experience printing to an impact printer and very little printing in WPF at all. I've printed scaled controls to standard paper before but that's it. Edit: Also I noticed from your SO question that you're using 816 pixels for 8.5 inches of paper, which in your case would be 0 margin. Most printers are going to need some kind of reasonable margin, so telling it to use 100% of the paper might be putting the whole thing on tilt. It may not fix your problem but it's probably going to be something you need to change anyway. Che Delilas fucked around with this message at 18:19 on Mar 15, 2013 |
# ¿ Mar 15, 2013 18:06 |
|
Yeah, tapping into PrintCapabilities would have been my next suggestion. And you're already trying to create a new custom PageMediaSize, which isn't working. I found a related problem with an alleged solution that might work for you. It involves creating a new print ticket, setting the custom PageMediaSize and then merging the ticket with the UserPrintTicket. code:
Disclaimer: I haven't tried this code, it's adapted from an answer I got on Microsoft Social of all places, so as usual for that site I fully expect it to fail miserably. Good luck. I'd be really interested to know if it works.
|
# ¿ Mar 15, 2013 18:59 |
|
GrumpyDoctor posted:Can anyone think of a reason that this function inside a mixed DLL: I've seen exceptions swallowed like that before, though admittedly in a straight C# application, not mixed. Are you calling this function from a form's "Load" event handler function? http://stackoverflow.com/questions/1583351/silent-failures-in-c-seemingly-unhandled-exceptions-that-does-not-crash-the-pr
|
# ¿ Jul 2, 2013 23:39 |
|
PhonyMcRingRing posted:Personally, I think it's due to them shoving the whole minimal/flat/hide everything into VS. If there's one program I use where I don't need things hidden on me it's VS. But we have to have a unified UI for all our products now, even if that means there's no color contrast or visual separation and you have to fight the UI to find loving anything. Because why not lump professional software developers into the same category as end users who can't read or tell left from right? Also, who decided that VS2013 should require IE10? What possible reason other than "we want to push our poo poo browser" could they have? You'd think they'd want more software developed for their operating system to keep it relevant, especially considering the poor showing from Windows 8. Are they trying to make us want to learn non-MS languages just to avoid having poo poo shoved down our throats? Because mission accomplished, guys!
|
# ¿ Dec 5, 2013 15:15 |
|
RICHUNCLEPENNYBAGS posted:Right, but why should the lifespan be so different if it's getting disposed after every request? I'm not talking about a static connection or anything. It's not necessarily bad on a technical level (that I know of), though I'm sure there are some corner cases where it won't get disposed the way you expect. It's more a design issue. Spraying data access logic at your Controller classes severely breaks separation of concerns, which is the point of MVC to begin with. Data access is such an orthogonal issue to an MVC app that it really should be handled in its own place; at minimum in its own class (some projects have it in its own project entirely). And really, moving each linq query out to its own method in a data access class somewhere doesn't really add a lot of complexity at all, if you don't bother with doing full dependency injection. It's a shame that every beginners guide and tutorial does it precisely the wrong way (dbcontext instantiated directly in the controller), in their haste to explain Actions and passing data through to strongly typed Views. I get why they do it, it just does damage to new developers and it's something you have to unlearn when you start doing big projects.
|
# ¿ Jan 4, 2014 09:03 |
|
RICHUNCLEPENNYBAGS posted:I understand that, but what if you have a separate class that, say, has methods like GetMyObject() or SaveApplicationObject() or whatever, rather than directly making DbContext calls, and that class is itself disposable? Then you can dispose it in the controller's dispose method and if you're using an interface you could go back and mock it later (yeah it should probably happen at the same time but I'm working on a really tight deadline to have a first release). That sounds to me like basically what we've been advocating. Make a separate class that manages your data access, with methods that represent what kind of data access operations you're doing. If that involves EF and DbContexts, then great. If it involves ADO SqlClient, that's fine too. Whatever. The point is, the Controller doesn't care how the data access is being accomplished, just THAT it is being accomplished. That said, you have a deadline. Here's what you have to consider: Some of the things we've talked about (notably IOC containers) add some initial complexity to a project, which is going to cost you time, especially if you're just learning about the more modern OOP concepts and tools (again, like IoC and IoC containers). Some projects are not worth adding that much complexity to. For example, little one-off utilities or internal web sites that are only going to be used by like 2 guys in a single department. It would be NICE to have a beautiful design where everything is loosely coupled and unit-testable and infinitely maintainable and extendable, but it's not always necessary. Beyond that, sometimes you just have to get poo poo done. If you're on a tight deadline, you have to make a judgement call about how far you need to go in that respect. If you're up against a wall, go with what's easiest to do, for you, right now. Get that poo poo out the door, because nobody will care how beautiful and extendable and maintainable the project is in the future if it isn't ready when they need it in the first place. Some people in here may disagree with me on this point, but that's been my (albiet limited) experience. Just realize that these choices you have to make will affect how difficult it is to extend and maintain the project in the future. The bigger the project is, the more good design will save your rear end. Make a judgement call.
|
# ¿ Jan 5, 2014 09:33 |
|
|
# ¿ Apr 28, 2024 20:41 |
|
I have a best practices/oop design question. It's not specific to .Net but that's what I'm working with, so here goes. I'm working on an MVC4 web application. In its domain model, it has an entity which I will call "Item". Each Item has a unique Sku number that is used to locate the item in a physical inventory (so Sku 1 is the first in the drawer, Sku 5 is farther back in the drawer, etc). When a particular Item is dispensed, its slot, and therefore its Sku number becomes available for use. When a new Item is added, we want to assign the first available Sku number to that Item. I also have an ItemRepository interface that defines all the CRUD for Items. My question is, where do I perform the calculation that finds the next available Sku? It's clearly a business rule, so it doesn't belong in any Controllers, but I feel like putting it in the ItemRepository is inappropriate; if I change the repository, I would have to re-create the Sku calculation. So where does the calculation go? This is a personal project for learning purposes with no deadline, so I'd like to do it right and learn a good habit.
|
# ¿ Jan 24, 2014 07:56 |