After some searching I discovered that it was because I wasn't using the Mail app as my default mail reader. After setting it back to Mail.app in the Mail Preferences window
the option to share via Mail appeared in the Photos Share menu. Tuesday, April 21, 2015
Emailing Pictures in new OSX Photos app
After updating to the new Photos app I tried to share a picture via email and was disappointed to see this option missing from the Share menu.
Clicking More in that menu opens the Extensions Preferences window where you can select with extensions you want to use and so I'm hoping this is just a result of the third party email reader application needing an update to configure itself as a Mac sharing extension.
Monday, October 7, 2013
More TFS woes
Disclaimer: TFS is not my VCS of choice. I use it because that is what the client site where I'm working uses.
I'd heard about it before but only just ran into it myself today. I'm referring to the TFS character limit which I've come to learn is actually a Windows character limit that is a holdover from older APIs. NTFS actually supports filenames in excess of 32000 characters yet windows APIs, and thus any tool built on top of those APIs, still has a limit of 260 characters. Apparently Microsoft doesn't intend to fix it (or didn't in 2011). If that's not technical debt then I don't know what is.
They have started addressing it to some degree in TFS 2012 with support for up to 400 character paths but on the server only.
I'd heard about it before but only just ran into it myself today. I'm referring to the TFS character limit which I've come to learn is actually a Windows character limit that is a holdover from older APIs. NTFS actually supports filenames in excess of 32000 characters yet windows APIs, and thus any tool built on top of those APIs, still has a limit of 260 characters. Apparently Microsoft doesn't intend to fix it (or didn't in 2011). If that's not technical debt then I don't know what is.
They have started addressing it to some degree in TFS 2012 with support for up to 400 character paths but on the server only.
Friday, April 5, 2013
Auditing DB actions using MVC 4 and Entity Framework
This is a post from sometime last year that for some reason I never published.
This post describes an approach for an ASP.Net MVC application with a database-first EF Model. I was using MVC 4 and EF 4.3. The project this was for had some requirements and standards that have to be met about the degree of auditing on at the DB level. Simply overriding the EF SaveChanges() method to catch all actions will not suffice as the DB would likely be accessed by other means outside of the MVC/EF application. So table based triggers was the way to go but how to pass the username through to the DB?
Instead of storing before and after values in each audit entry row, the before values can be retrieved from the previous entry (inserts are also audited) although this makes queries on the audit data slightly complicated. Could also store only the columns that changed in the XML....
This post describes an approach for an ASP.Net MVC application with a database-first EF Model. I was using MVC 4 and EF 4.3. The project this was for had some requirements and standards that have to be met about the degree of auditing on at the DB level. Simply overriding the EF SaveChanges() method to catch all actions will not suffice as the DB would likely be accessed by other means outside of the MVC/EF application. So table based triggers was the way to go but how to pass the username through to the DB?
The approach described below builds of off concepts outlined in the following articles:
- http://lgsong.blogspot.ca/2012/01/contextinfo-and-entity-framework.html This article gives the general idea of what I'm doing here.
- http://jmdority.wordpress.com/2011/07/20/using-entity-framework-4-1-dbcontext-change-tracking-for-audit-logging/ See this article if you're using a Code-First approach (this was not an option for us).
- http://weblogs.asp.net/jgalloway/archive/2008/01/27/adding-simple-trigger-based-auditing-to-your-sql-server-database.aspx The code in this article was full of syntax errors and was missing spaces and required a little clean up in order to work with it but the ideas are good. I adapted his approach of dynamically adding triggers to all the tables to work with the Audit table schema we were using.
The high level description of the approach is as follows:
- Create Audit_Log and Audit_Comment tables in your DB
- Add a stored procedure that takes a username and a comment string and inserts them into the comment table saving the generated comment_id and username in the database CONTEXT_INFO.
- Add insert, update and delete triggers to each table that will first extract the comment_id and username from the ContextInfo() and then use those when inserting the audit details into the Audit_Log table.
Other Suggestions
Use an XML column to reduce the number of inserts.Instead of storing before and after values in each audit entry row, the before values can be retrieved from the previous entry (inserts are also audited) although this makes queries on the audit data slightly complicated. Could also store only the columns that changed in the XML....
Threading Woes
Until recently I've gotten away with only looking at or making minor tweaks to VB.Net code. I've now been tasked with modifying a web service that involved reviving some cached values in a background thread so the user wasn't left waiting for the task to finish. If the values were cached the service responded well but once the cache expired there was a long wait (minutes) for any request that came in while the cache was rebuilt. The solution, until a replacement service is completed, was to preemptively rebuild the cache in a thread prior to expiry. The solution involved locks to ensure only one thread is rebuilding the cache at once and thus prevent cycles spent needlessly rebuilding the cache multiple times. Locks in VB are created using SyncLock which is like lock in C#. The challenging bit for me (and I now know way more about VB than I ever intended to) was that the Static keyword in VB does not work the way you would expect coming from a C# perspective (or any other perspective I've encountered for that matter) and can only be applied to local variables and properties. It turns out what I really wanted was a Private Shared ReadOnly object although it took me some time and plenty of tinkering to come to that conclusion.
Also, despite the great thread debugging tools available in Visual Studio, print statements proved invaluable in actually seeing what order things were happening in and seeing when the locks were actually working or not. Sometimes the simplest approach is the most effective.
Also, despite the great thread debugging tools available in Visual Studio, print statements proved invaluable in actually seeing what order things were happening in and seeing when the locks were actually working or not. Sometimes the simplest approach is the most effective.
Friday, September 7, 2012
jQuery UI Tabs issue in MVC 4
I was trying to set up the jQuery UI Tabs sample in an ASP.Net MVC 4 application and got the following error in the console:
Uncaught TypeError: Object #<Object> has no method 'tabs'
It turned out that jQuery was not yet loaded at the time the .tabs() method was being called. Scripts must be loaded in the correct order or the code they're referencing may not be available. I had the bit in the document ready block but was still having a problem. The problem in the MVC case seemed to be the mix of using both MVC bundles and script tags. There is likely a proper way to do it if I were to read more about bundles and when they're loaded, etc.
I decided to put all the script resources into bundles and loaded them that way and I left the bit of code calling $('#tabs').tabs() in a script tag. Still no luck. So I deleted that script tag, loaded my page, made sure all scripts were available and then in the chrome javascript console I entered $('#tabs').tabs() and BAM, the tabs appeared. This proved that the script fragments were not being run in the order I had expected so I put the code in a separate js file and loaded it in a bundle as well and everything worked.
So if you're using Bundles, it appears your best bet is to use them across the board and not mix and match with inline script tags.
Thursday, September 6, 2012
Understanding the Resistance to Agile
I have been reading some architecture documentation for a set of services that are part of a much larger system. In one section of the document, after a brief (and incorrect) description of Entity Framework, I encountered this paragraph:
No wonder there is resistance to Agile Development when there are people spreading falsehoods like this around.
I still can't believe what I've just read... not to mention I read it in an overly "comprehensive" 67 page document. As if a description of EF was necessary; a link to the official Microsoft documentation on EF would have sufficed.
This framework was chosen to support agile development. The developer does not need to write any data access logic, other than creating the entity data model, and the framework was built to work directly with the Windows Communication Foundation DataService class.Firstly, this statement misconstrues the meaning of Agile Development. Agile Development has nothing to do with what code is written or which framework is chosen. Agile development is about enabling the developers and about being able to develop amidst a rapidly changing environment towards an often incorrectly or partially defined target. The first value defined by the agile manifesto (http://agilemanifesto.org/) states that we value "Individuals and interactions over processes and tools" yet this statement is all about choosing tools (EF and WCF).
No wonder there is resistance to Agile Development when there are people spreading falsehoods like this around.
I still can't believe what I've just read... not to mention I read it in an overly "comprehensive" 67 page document. As if a description of EF was necessary; a link to the official Microsoft documentation on EF would have sufficed.
Monday, August 20, 2012
TFS... meh.
I've recently switched jobs and am settling in to a new work environment; learning new practices and procedures. One new thing I've been exposed to here is using Team Foundation Server for source control. I had heard it was a huge improvement over Visual Source Safe (which wouldn't take much to accomplish) but that was about the only comment I'd get from people using it. Now that I've had a little bit of time to try it out I'm beginning to form opinions. My first impression was that TFS has a lot more to offer than just source control and if a team were taking advantage of those additional features (like Team Build, Project Management Features, etc.) then I could see the advantages of it. Unfortunately, just as a VCS tool it leaves something to be desired. I'm planning to leverage Team Build and bring some continuous integration into play in the new environment here but that will be fuel for another post.
TFS First Impressions
Like the title of this post says, my general first impression was just that, "meh". There was still a flavour of VSS with all the locks and how I have to actually "check out" a file before I can edit it. If there is an image or a word document in the solution, for example, that I need to modify for some reason, I have to first, check the file out in Visual Studio, then open the file from windows explorer using word or whatever third party application I need to make the change after which I then check in the changes from within Visual Studio. It all just seems so inconvenient. I don't know how many times I've opened a file in the past week, made some changes, and tried to save them only to be told the file is read-only... I know it's a habit and I'll eventually be broken of it, but it's still an extra step. It slows development down. Thankfully, Visual Studio is smart enough to check a file out for me when I start to edit it. But if I want to open some javascript files in a text editor because I like the way that editor handles jslint or code completion or feature X, I still have the same problem.
Now the above is going to prompt comments about how there are tools like Team Explorer that have shell extensions that will let me do it from the windows explorer context menu and my reply to them would be that I've installed that but it's still a bit annoying to use. Didn't even work at first and my icon overlays don't seem to be working either... they're always the same green triangle, they don't ever change...
Merging is SLOOOOOOWWWW....
Merging conflicts is a pain which probably is why people try to work in a way to avoid conflicts at any cost. The built in merge/compare tools are lackluster and feature poor and once you've completed the merge, saving any changes takes much longer than it should and during this save operation, the strangest thing happens, all the Visual Studio windows are redrawn in the display. They go all white for a second or two and then slowly everything comes back bit by bit. I'm not sure why this has to happen but it does. Now I understand we're not using the most recent version of TFS but it is still strange behaviour that renders the system unusable for several seconds.
Shelving/Unshelving: great in concept, annoying in practice.
When I first read about shelving changes in TFS I thought, "oh, just like stashing in git" which is a git feature I admittedly haven't used a whole lot either. At any rate, it sounded like a useful feature and thought I'd try it out. I had been working on some code and needed to switch to something else so I figured I'd give it a go; they weren't really huge changes so I could afford to do them again if the it didn't work as I expected. I shelved the changes, did the other work and checked it in. I didn't unshelve my previous changes immediately and came back to it a day or two later. The unfortunate thing was that my newer changes did not work with the shelved changes and the shelved changes had no connection to the revision on which they were made which basically rendered them useless and I ended up just doing them all over again in context of the more up to date code. I found it to be a frustrating experience mostly due to my expectations not being met. I'm not one to give up so easily and so have continued to play with them on occasion and they have some use as long as you can work within the limitations of the feature. I think most of my disappointment comes from the the feature not being as cool or useful as it sounded when reading about it in the documentation.
Thursday, August 16, 2012
Playing with ASP.Net MVC 4
For an intro to MVC 4 have a look at this article. I'm enjoying the scaffolding and the Razor templates (which were released with MVC 3 but hadn't played with them yet) and the Code First approach to using Entity Framework.
Thursday, July 26, 2012
Words to live (work) by
Martin Fowler tweeted a bliki retread to his article about RigorousAgile today. My favourite line is this one:
...agile methods fundamentally expect teams to decide what process to follow and furthermore expect teams to actively and regularly change their process.I found it to be a very concise description of agile methods that hits those key points perfectly. It's all about continuously improving and I have yet to find an environment as rewarding to work in as being part of a team that has that outlook.
Wednesday, March 28, 2012
Decoding Base64 Encoded Strings with CherryPy
I wanted to write a simple web app for decoding base64 encoded strings. I wanted something that was very easy to use that wouldn't require a large amount of up front learning. I've done some stuff with Google App Engine Python SDK before and thought about using that (and I might still do that) but decided to look at some other frameworks. I came across CherryPy which I had heard of before but never really looked at. To get a basic Hello World app working was very quick and easy and I liked that it has a built in web server so I wouldn't have to configure Apache or some web server to get it working. It's so minimal that it just looks like python code with embedded html and if you use something like Mako templates it looks even cleaner but it does add a little more complexity. Mako templates are very easy to use however and if you are building larger scale applications they are well worth it.
Below is the code I came up with. It is a simple website with 2 pages. The first is for decoding base64 encoded strings and gives you the result as a file to download. The second is for encoding files and has a file upload form that gives you the resulting base64 encoded string as a result.
To run it, you need python and cherrypy installed (I'm using python 2.6.4 and cherrypy 3.2.2). Save the below code as
And then view it in your favourite browser at http://localhost:8064/
Below is the code I came up with. It is a simple website with 2 pages. The first is for decoding base64 encoded strings and gives you the result as a file to download. The second is for encoding files and has a file upload form that gives you the resulting base64 encoded string as a result.
To run it, you need python and cherrypy installed (I'm using python 2.6.4 and cherrypy 3.2.2). Save the below code as
base64Decoder.py and use the following command to run it:python base64Decoder.py
And then view it in your favourite browser at http://localhost:8064/
import base64 import cherrypy from cherrypy.lib.static import serve_file class base64Decoder(object): def index(self): return """ <html> <head><title>Base 64 Decoder</title></head> <body> <h2>Base 64 Decoder</h2> <a href="encoder">Switch to Encoder</a> <h2>Paste in the base 64 encoded string</h2> <form action="decode" method="post" enctype="multipart/form-data" target="_blank"> <textarea id="textToDecode" name="textToDecode" rows="5" cols="40"></textarea> Name of output file: <input type="text" id="fileName" name="fileName" /> <input type="submit" value="decode"/> </form> </body></html> """ index.exposed = True def encoder(self): return """ <html> <head><title>Base 64 Encoder</title></head> <body> <h2>Base 64 Encoder</h2> <a href="decoder">Switch to Decoder</a> <h2>Upload a file to encode</h2> <form action="encode" method="post" enctype="multipart/form-data" target="_blank"> filename: <input type="file" name="myFile" /> <input type="submit" value="encode"/> </form> </body></html> """ encoder.exposed = True def encode(self, myFile): cherrypy.response.headers['Content-Type'] = 'text/plain' data = myFile.file.read() return base64.encodestring(data) encode.exposed = True def decode(self, textToDecode, fileName): cherrypy.response.headers['Content-Type'] = 'application/octet-stream' dis = 'attachment; filename="%s"' % fileName cherrypy.response.headers['Content-Disposition'] = dis outstr = base64.decodestring(textToDecode) return outstr decode.exposed = True decoder = index cherrypy.server.socket_port = 8064 cherrypy.quickstart(base64Decoder(), '/')
Thursday, October 13, 2011
iOS 5 upgrade issues
I updated my iPhone 4 yesterday to iOS 5. I just wanted to say, what a frustrating experience. I first did a system update on my mac to get the latest iTunes. I synced my phone to get all the photos and recent purchases off of it. Then when iOS 5 became available I went ahead with the update. iTunes took a backup of my phone and away it went. iOS 5 downloaded without any issue and once complete I went ahead with updating my phone. It seemed to be proceeding without any problems, it wiped out my phone and attempted installing iOS 5. During the "Verifying restore with apple" stage it failed to connect to the apple update servers and it took a turn for the worse. It seems apple was unprepared for the number of people trying to update on day one and the update servers were timing out. Because the update had started, I was left with a blank iOS-less phone, basically a pretty black paperweight. It took several attempts over several hours to finally get iOS 5 installed but the fun didn't end there. Next was the restore of the backup that was taken just before the update process began. This too failed (with error -34). Several attempts seemed to solidify to me that the restore option was not going to work. Fortunately I had synced and imported everything before I began so I wasn't really worried about losing any data. My phone was in a usable state, it just wanted me to do some preliminary setup. So I went ahead with the setup but because it had only partially restored things all of my apps that were not bundled with the OS would crash. I had already set up iCloud on my Mac and so I decided to just set up the phone and re-sync it from iTunes. I had to reconfigure all my sync rules but after syncing everything seems to be working fine again. The only complaint so far is that it doesn't let me sync contacts,etc. with both iCloud and Google. I can see possible conflicts arising if trying to sync with multiple sources but it would be nice to have both...
A little frustrated and I still haven't had much time to appreciate having iOS 5. So far all I can say is the new notification centre is nice and I'm not yet convinced having music and videos separated into two separate apps is the better way to go.
A little frustrated and I still haven't had much time to appreciate having iOS 5. So far all I can say is the new notification centre is nice and I'm not yet convinced having music and videos separated into two separate apps is the better way to go.
Friday, October 7, 2011
Teacup Programming
Teacup Programming is a variation on pair programming.
Why teacups? While sitting around a round table during a team retrospective where we had mentioned pair programming the conversation drifted a little when someone said it felt like we were sitting in a teacup ride or something. Naturally, this led to combining the two ideas and teacup programming was born.
The idea is based on amusement park rides where the rider spins a wheel in the centre of the ride to increase the spinning velocity of the rider's individual car. The most widely known example of this is the Teacup ride at Disneyland.
Requirements
Steps
1. Sit the programmers around the table with a computer in front of every other programmer.
2. Each programmer with a computer begins working with the programmer on his or her right.
3. After a designated period of time, say 30 minutes, the pairs switch. This is done by either rotating the table one spot to the right or having everyone move left one spot so the programmer on the right from each previous pair is now sitting in front of a computer.
4. Again, each programmer with a computer then begins pairing with the programmer on their right (this is a consistent rule for creating pairs) and the timer is reset for another 30 minutes.
5. Goto 3.
The key point in this rotation system is to always have the one programmer from a previous pair remain working on the same computer and thus on the same problem to help reduce lost time due to context switching. Also, everyone at the table gets a look at each problem which means more eyes looking at the code. The drawback is that one programmer only ever works with two others at most.
Variant
A variation to increase the number of pairing combinations is to have the person relinquishing control of a computer get up and "leap frog" positions one direction or another. This adds more complication to the rotations but allows an individual to pair with more people in the group.
We have yet to actually try this out and so cannot say whether it is a viable technique or not but I think it does have some merit and there may even be some specific situations where it might be best applied such as at a hack-a-thon where there is a long list of problems or bugs trying to be solved none of which are too lengthy or difficult or for practicing for a programming contest where people are just trying to solve as many problems as possible.
If anyone gets around to actually attempting this please post a comment with the results.
Why teacups? While sitting around a round table during a team retrospective where we had mentioned pair programming the conversation drifted a little when someone said it felt like we were sitting in a teacup ride or something. Naturally, this led to combining the two ideas and teacup programming was born.
The idea is based on amusement park rides where the rider spins a wheel in the centre of the ride to increase the spinning velocity of the rider's individual car. The most widely known example of this is the Teacup ride at Disneyland.
Requirements
- An even number of programmers
- a table (round is preferred but not necessary and a rotating table is even better)
- one computer for every two programmers
Steps
1. Sit the programmers around the table with a computer in front of every other programmer.
![]() |
| table setup |
![]() |
| pairs with person to the right |
![]() |
| rotate the table one spot |
![]() |
| after rotation |
![]() |
| again pair with person to the right |
Variant
![]() |
| programmers "leap-frog" |
We have yet to actually try this out and so cannot say whether it is a viable technique or not but I think it does have some merit and there may even be some specific situations where it might be best applied such as at a hack-a-thon where there is a long list of problems or bugs trying to be solved none of which are too lengthy or difficult or for practicing for a programming contest where people are just trying to solve as many problems as possible.
If anyone gets around to actually attempting this please post a comment with the results.
Remaking the bed...
I follow @unclebobmartin on twitter and was also getting caught up with his blog posts and have been enjoying his rant-like video posts. I particularly liked this one about Architecture Deference and even tweeted saying so. I found it to be a good pre-cursor to this post on Screaming Architecture which I'm sure came partly as a result of the first.
I've been dealing with issues in some of our apps and haven't been able to put my finger on where they stem from and these posts really seemed to highlight for me what it likely was in the approach that caused these issues. From the running of tests taking too long to too much focus on the aspects that don't really matter and should be deferred, I think I know where many of the issues lie. The only problem now is figuring out how to fix it once it's been done... or is it too late? Would it be too much to decouple the model, or the architecture, from the frameworks and tools to make it not worth the effort? Do we just say lesson learned and take a more correct approach the next time around?
How tired am I? Do I just want to go to sleep in the bed that's made or do I remake it? Can it be remade?
I've been dealing with issues in some of our apps and haven't been able to put my finger on where they stem from and these posts really seemed to highlight for me what it likely was in the approach that caused these issues. From the running of tests taking too long to too much focus on the aspects that don't really matter and should be deferred, I think I know where many of the issues lie. The only problem now is figuring out how to fix it once it's been done... or is it too late? Would it be too much to decouple the model, or the architecture, from the frameworks and tools to make it not worth the effort? Do we just say lesson learned and take a more correct approach the next time around?
How tired am I? Do I just want to go to sleep in the bed that's made or do I remake it? Can it be remade?
Friday, January 21, 2011
Making Mock Data Fun
While looking at documention for Pivotal Tracker's Activity Web Hook we were looking at the following piece of XML they provide as sample data:
<?xml version="1.0" encoding="UTF-8"?>
<activity>
<id type="integer">1031</id>
<version type="integer">175</version>
<event_type>story_update</event_type>
<occurred_at type="datetime">2009/12/14 14:12:09 PST</occurred_at>
<author>James Kirk</author>
<project_id type="integer">26</project_id>
<description>James Kirk accepted "More power to shields"</description>
<stories>
<story>
<id type="integer">109</id>
<url>https:///projects/26/stories/109</url>
<accepted_at type="datetime">2009/12/14 22:12:09 UTC</accepted_at>
<current_state>accepted</current_state>
</story>
</stories>
</activity>
They also show the following example for creating a new user:
e.g. Name, email, or James T. Kirk (JTK) <kirk@starfleet.edu>
We couldn't help but laugh and think that pivotal must be a fun place to work. While discussing other types of funny mock data we'd seen both in our own office and elsewhere we had the thought that having fun mock data could help get developers more involved with testing.
In my experience most developers dislike creating data to test with. I'm not talking about making mock objects but making actual test data that mirrors what you'd expect to have in a real system. It's tedious and not very fun. Nothing beats real data of course, however, a good set of mock data makes it much easier to test an application either manually or in some automated CI system so it is definitely something you want to have when developing an application.
Tuesday, July 6, 2010
Switching to PivotalTracker
For our SCRUM development we have used a variety of tools to plan and track our work.
Mingle
We used Mingle for a long time but found that because it is so customizable it makes it very easy to overcomplicate your project and process. We also spent a large amount of time configuring, setting up and tweaking mingle to create the ideal project template. Mingle is also very slow and seems to require a server with a huge amount of resources to run smoothly.
Scrum Ninja
Scrum Ninja has a lot of nice features and seems to be going in the right direction but it was very glitchy and we even lost some data at one point. We were able to get most of it back through their support but it was definitely a hassle. Searching didn't work very well and although the card wall view is a nice idea it can be hard to read. The export format is relatively useless leaving out important data like dates. It wasn't even worth trying to parse the exported text with a script to extract what we wanted.
Pivotal Tracker
Pivotal has done a very nice job with their Tracker product. We first tried at the same time as ScrumNinja and first impressions left us feeling it was more restricted or had fewer features in some areas. We gave it another go and now realize it has a much simpler interface that we've found frees us up to just work on the project rather than spending time setting it up in the tool. It has several integrations with other projects and an open API for custom integrations. We've also made suggestions and bug reports and had very quick responses and fixes. It also uses csv as an export format. All in all we're very happy with Tracker so far. Plus, it's free.
Mingle
We used Mingle for a long time but found that because it is so customizable it makes it very easy to overcomplicate your project and process. We also spent a large amount of time configuring, setting up and tweaking mingle to create the ideal project template. Mingle is also very slow and seems to require a server with a huge amount of resources to run smoothly.
Scrum Ninja
Scrum Ninja has a lot of nice features and seems to be going in the right direction but it was very glitchy and we even lost some data at one point. We were able to get most of it back through their support but it was definitely a hassle. Searching didn't work very well and although the card wall view is a nice idea it can be hard to read. The export format is relatively useless leaving out important data like dates. It wasn't even worth trying to parse the exported text with a script to extract what we wanted.
Pivotal Tracker
Pivotal has done a very nice job with their Tracker product. We first tried at the same time as ScrumNinja and first impressions left us feeling it was more restricted or had fewer features in some areas. We gave it another go and now realize it has a much simpler interface that we've found frees us up to just work on the project rather than spending time setting it up in the tool. It has several integrations with other projects and an open API for custom integrations. We've also made suggestions and bug reports and had very quick responses and fixes. It also uses csv as an export format. All in all we're very happy with Tracker so far. Plus, it's free.
overcomplicating things with the repository pattern
The Repository pattern was used in a project by some team members 6 or so months ago and it's being mentioned again along with concepts of an Aggregate Root in discussions on refactoring another project. Both of these projects were C# projects using LINQ to SQL. While working on the first project I kept thinking that the repository pattern seemed to just over complicate things and I couldn't see what real benefit it brought to a fairly simple application. Now, I've done some further reading on Aggregate Roots and found ties to the repository pattern again. As I read through several definitions I kept thinking that the main benefits are already provided via LINQ and implementing it on top seemed to only add another abstraction layer. I did some more searching on the subject and found this article: Repository is the new Singleton and it just echoed everything I was thinking.
Creating a repository for data that is already in your DB is overkill when you are using LINQ (and likely any modern ORM) for accessing that data since the data access provided by LINQ is itself making use of the repository pattern . A good place where the repository pattern would be useful is where you may have different sources of data.
Here is another interesting article about the Purpose of the Repository Pattern that talks about some of the issues when using this pattern along with LINQ. The DataContext issues he mentions exist generally in a Web Application built on LINQ and not just when using repositories. Our team got around some of the DataContext issues by using a DataContext Factory that we found that creates a scoped DataContext within the HttpContext and while within the scope of the HttpContext it always returns the same DataContext. This helps keep anything within the HttpRequest in the same Unit of Work. It was also written to work within the current thread if a HttpRequest is not available (a non-web app).
Creating a repository for data that is already in your DB is overkill when you are using LINQ (and likely any modern ORM) for accessing that data since the data access provided by LINQ is itself making use of the repository pattern . A good place where the repository pattern would be useful is where you may have different sources of data.
Here is another interesting article about the Purpose of the Repository Pattern that talks about some of the issues when using this pattern along with LINQ. The DataContext issues he mentions exist generally in a Web Application built on LINQ and not just when using repositories. Our team got around some of the DataContext issues by using a DataContext Factory that we found that creates a scoped DataContext within the HttpContext and while within the scope of the HttpContext it always returns the same DataContext. This helps keep anything within the HttpRequest in the same Unit of Work. It was also written to work within the current thread if a HttpRequest is not available (a non-web app).
Tuesday, February 9, 2010
Is the industry moving away from Agile?
I don't think so.
I'm writing this in response to a link to this article on slashdot that a friend sent me asking the question which I've used as the title for this post. (The slashdot article references this blog post which is a good and informative read in itself and I found I agreed with many of his points. What starts as an emotional rant turns into a very well presented article.)
There isn't just one way of doing development or just one way of doing agile; hence the name agile. I thought the first poster on slashdot hit it on the head especially with his comments about having the right people and making adaptations to your business.
The author leads into the article complaining about agile but later talks about how many other methodologies can also be successful. The important thing in my mind is picking the right approach for the job (or team even; some methodologies only work with a certain type of people) and also understanding that methodology properly. In fact, the understanding must come first to be sure that you do pick the right approach for your team/project.
The author made a good point about how some people use the words "agile" and "scrum" interchangeably. It is my opinion that these are the teams that fail at agile. It could be that some see agile as being less structured and as a result end up thinking there are fewer rules and less accountability. An agile approach may give the developers more leeway and freedom but with that comes more responsibility. My experience has shown that a junior team usually cannot succeed in these circumstances. They typically will not have the experience required to make the design and implementation decisions that are usually made by someone else in a different model. It's been a challenge to overcome with some of our teams.
We use SCRUM outwardly but also take the XP approach mentioned by Kent Beck in "Extreme Programming Explained" and implement changes slowly. We reflect each week in our sprint retrospective on how those changes helped/hindered us and we also talk about new ideas and ways to improve our process. Yes, we follow a scrum model but one that we have adapted to our needs. We also know that it is more than just doing this list of things and then we'll have it right. We know that the business needs change, the business itself changes and that we need to be able to change and adapt in order to keep pace. I feel that with the right mix of people and support from management agile can be very effective.
Although we don't do game development where I work, I had previously found this pdf about lessons learned implementing SCRUM at Bioware and one of the key things I took from that was that they also ended up adapting SCRUM to their own needs. I think this is key to success with any methodology; being able to take what works and adapt where you need to.
Thursday, January 21, 2010
Setting up TortoiseGit to work with SSH on a different port (not port 22)
So recently we've had some headaches giving users on Windows machines access to our git repository (me being one of them but not the first). In searching for a solution to this problem I found several people with the same issue but having to use various workarounds or actually change their ssh port back to 22. All of the workarounds were out of the question for me but I knew there had to be a way to do it. Basically I just followed some of the better posts about using Git on Windows out there with a couple minor changes.
Here are links to a few of the posts I looked at while trying to figure this out:
The important pieces to make sure you get it working are these:
- Be sure you choose the OpenSSH option when installing msysgit
- Be sure you choose the OpenSSH option when installing TortoiseGit
- create a .ssh/config file and enter something like the following
Host name_of_host_where_your_git_repo_is
User git
Hostname name_of_host_where_your_git_repo_is
Port port_number
PreferredAuthentications publickey
IdentityFile "/path/to/your/openssh/private/key"
And you should be good to go. I actually set up msysgit and my ssh config file first, then I made sure that I could connect and then I installed TortoiseGit.
Tips:
- If you created your private key using puttygen then you'll need to export it (using puttygen) as an OpenSSH key.
- While testing your connection you can use ssh -v git@github.com (or @ your own host even) to see what ssh is doing and to make sure it is finding your key correctly.
- If your openssh key is located at C:\users\myuser\keys\key.ssh then the path to your IdentityFile should be like this: /c/users/myuser/keys/key.ssh
Friday, October 9, 2009
SQL Server 2008 express
I spent the better part of today attempting to get my (Windows Vista Business :/ ) system to a state where I was able to run the installer for SQL Server Management Studio 2008 so that I could access a 2008 sqlexpress instance running on another machine. It's finally running the installer as I type this and the annoying thing is that my friend was able to access the DB using RazorSQL (usign the jtds driver) on his Mac without a problem. It's infuriating that I have to go through all this hassle when I could have just used a non-Microsoft tool to do the job. I don't see why SQL Server Management Studio 2005 can't access the database at the same level as jtds. I suppose if I added an odbc connection on my computer to the db then I could have accessed it that way...
The install is now finished... Hopefully I can at least get some work done now.
The install is now finished... Hopefully I can at least get some work done now.
Tuesday, September 29, 2009
Errors with an Upgraded Rails version
NameError: uninitialized constant ApplicationControllerI've had to take a shelved project written for rails 2.1.1 and try to get it running again and ran into an issue getting it to work with the version I have on my machine; namely rails 2.3.4. Thanks to this post I was able to quickly overcome the most obscure error rather quickly.
Subscribe to:
Posts (Atom)








