Pages

Showing posts with label patterns. Show all posts
Showing posts with label patterns. Show all posts

Wednesday, June 4, 2014

Formatador de T-SQL "para os pobres"

Um developer deve sempre usar um conjunto de coding standards de forma a que o código siga sempre as mesmas convenções facilitando a sua leitura e compreensão.

A nível do Visual Studio nunca tive muitos problemas, mas a nível do T-SQL ... a historia é outra. Uma ferramenta que ajuda e muito é o addin "Poor Mans T-SQL" que implementa os coding standards definidos por Steven Bates numa série de posts nos MSDN Blogs.

Este addin está disponível neste link de várias formas: Stand alone app, Notepad++ addin, online, ...

Depois de instalado basta abrir/reiniciar o SQL Server Management Studio, e o addin está disponível no menu Tools.



Fonte: Poor Mans T-SQL formatter

Wednesday, May 28, 2014

Correr um serviço windows como uma aplicação de consola


Um dos problemas comuns quando se desenvolvem setrviços windows é conseguir fazer debug a eles... Ou fazemos um attach process e corremos o risco de apanhar o processo já a meio da sua execução ou então criar um projecto consola aparte só para este efeito.

Uma forma de facilmente usar o mesmo projecto para correr o serviço windows ou conseguir lançar como um projecto consola é usar uma flag de ambiente que nos indica se estamos a correr no contexto do visual studio ou não.

Para isso basta seguir este pequeno template e conseguimos correr o projecto com um F5 e fazer debug ao código ou então usar o InstallUtil e instalar o projecto como um serviço windows.

 public static int Main(string[] args)  
 {  
  if (!Environment.UserInteractive)  
  {  
   // Startup as service.  
  }  
  else  
  {  
   // Startup as application  
  }  
 }  


Fonte: Easier way to start debugging a windows service in C#

Thursday, March 20, 2014

Usar herança nos parâmetros dos métodos na WebApi

Num dos desenvolvimentos em que estou envolvido surgiu a necessidade de usar herança num dos parâmetros de entrada dum método na WebApi. O que eu quero dizer por usar herança é ter na assinatura do método um tipo base e depois quando os vários componentes chamam o método passam tipos derivados com informação mais especifica.

Ora então temos algo como:
 void Process(BaseEvent baseEvent);   
   
 public class BaseEvent   
 {   
   public int Id { get; set; }  
   public DateTime EventOn { get; set; }  
   public string User { get; set; }  
 }   
   
 public class LocationEvent : BaseEvent  
 {   
   public decimal Latitude { get; set; }  
   public decimal Longitude { get; set; }  
 }   
   
 public class VehicleEvent : BaseEvent  
 {   
   public string LicencePlate { get; set; }  
 }   

O problema surge quando os vários componentes chamam a WebApi, passam os tipos derivados, a WebApi recebe o tipo derivado mas faz sempre deserialize para o tipo base.

Para dar a volta à questão temos de controlar o deserialize através dum JsonConverter e mais uns pózinhos mágicos :)
  1. Adicionar o pacote nuget do Newtonsoft.Json
 Install-Package Newtonsoft.Json  
  1. Alteramos a classe base para ter o tipo que realmente é
 public class BaseEvent    
 {  
   public string typename { get { return this.GetType().Name; } }  
   
   public int Id { get; set; }  
   public DateTime EventOn { get; set; }  
   public string User { get; set; }  
 }   
  1. Criamos um JsonConverter 
 public class BaseEventJsonCreationConverter : JsonConverter  
 {  
   public override bool CanWrite  
   {  
     get  
     {  
       return false;  
     }  
   }  
   
   public override bool CanConvert(Type objectType)  
   {  
     return typeof(BaseEvent).IsAssignableFrom(objectType);  
   }  
   
   private BaseEvent Create(Type objectType, JObject jObject)  
   {  
     var typename = jObject.Value("typename");  
     if (typeof(LocationEvent).Name.Equals(typename))  
     {  
       return new LocationEvent();  
     }  
     else if (typeof(VehicleEvent).Name.Equals(typename))  
     {  
       return new VehicleEvent();  
     }  
     else  
     {  
       return new BaseEvent();  
     }  
   }  
   
   public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)  
   {  
     if (reader.TokenType == JsonToken.Null)  
       return null;  
     // Load JObject from stream   
     JObject jObject = JObject.Load(reader);  
   
     // Create target object based on JObject   
     BaseEvent target = Create(objectType, jObject);  
   
     // Populate the object properties   
     serializer.Populate(jObject.CreateReader(), target);  
   
     return target;  
   }  
   
   public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)  
   {  
     throw new NotImplementedException();  
   }  
 }
  1. Decoramos a classe base com JsonConverter
 [JsonConverter(typeof(BaseEventJsonCreationConverter))]  
 public class BaseEvent 
 {  
   . . .   
 }  

E agora a WebApi já faz o deserialize dos objectos correctamente :)


Fonte: Deserialising Json to derived types in Asp.Net Web API

Friday, January 31, 2014

Programação Orientada a Gambiarra

Foi este post que vi no facebook que me fez arrancar com o blog, na altura achei tanta piada que me lembrei de fazer o post com a cheat sheet que usavamos na finsolutia.

E realmente faz todo o sentido também deixar aqui os slides para mais tarde recordar :)

 

Monday, January 27, 2014

Cheat Sheet: FAIL - Anti-Patterns and Worst Practices

Fica aqui a cheat sheet que usavamos na finsolutia, muitos destas más praticas/padrões não são usuais ... mas outros são pão nosso de cada dia :) 


1) Principles of programming
DescriptionPrefer
FBRFast Beats RightMore important to deploy something that appears to work, than to spend time ensuring "correctness""Continuous attention to technical excellence and good design enhances agility" - Agile Manifesto
FCDFeeping Creaturitis DrivenJust when the end is in sight, someone adds just one more feature they are desperately in love with"Deliver working software frequently, from a couple of weeks to a couple of months, with a preference to a shorter timescale." - Agile Manifesto
ADPAssumption Driven ProgrammingAssume the user will only use your software the way you mean for them to.Practice defensive coding. Watch how users attempt to use the software.
Treat handling the unexpected like any other feature.
TPTelemarketer PrincipleThe best way to retain control of what your code does is to manage exactly which objects it uses and what calls it makes at all time.The Dependency Inversion Principle can be used to correct this kind of code.

2) Anti-Patterns
DescriptionPrefer
SCPStatic Cling PatternThe easiest way to add functionality or track state is via static/global methods and objects. The Singleton Pattern is also your best friend!Dependency Inversion Principle. Your code should depend on interfaces, not static calls which cannot be injected. Static methods are death to testable code.
VSPVestigial Structure PatternDon't remove code that's no longer used just in case it's needed later! If you're really brave, comment the code but leave it in there.VSP is often a symptom of a muddled architecture, where it is difficult to tell where one feature begins and another ends.
FOOFlags Over ObjectsInstead of using objects, polymorphism, or delegation, it's much faster to just add a flag to a class and expose it. Who needs inheritance?Instead of checking a flag before performing and action, tell the object what to do and let it polymorphically do so.
TGCThe God ClassStrive to create one class to rule them all, a master class, capable of doing anything and everything your application might require.Follow the Single Responsibility Principle

3) Worst Practices
DescriptionPrefer
FOIFound on InternetSearch engines these days are smart; obviously the first blog post found that appears to solve the issue at hand must be the best approach based on our collective wisdom. Get it to compile and move on.Write a spike solution to ensure you understand the code. Or be sure to write some tests that confirm the code behaves as you expect. Review other approaches - are you asking the right questions?
POPremature OptimizationAll code written should be optimized for performance, even if the resulting design is less clear or elegant, or if the code is question is nowhere near the critical path for the application.Define performance requirements. Write tests that validate these requirements are being met. Do not optimize unless these tests fails. Identify bottlenecks don't blindly make "fixes".
CPCCopy-Paste-CompileThe feature you're working on is nearly identical to one already in the system. Just copy, paste, and get the code to compile and you're done!Keep your application code DRY. Refactor common code into shared modules when it makes sense to do so (avoid introducing excessive coupling).
CFVCopy Folder VersioningWhen really big changes are imminent, there's nothing like creating a copy of the current code folder to reassure you that you can always roll back.Use source control
GHGolden HammerYour favorite language, framework, library, or tool can do anything! wield it with confidence, and ignore anybody who tells you another tool might be better suited.Become familiar with a variety of languages, tools, and frameworks. Keep an open mind as you approach problems.
STShiny ToyDid you hear about the latest beta (tool/language/framework)? I'm sure it will solve all of our application's problems.Prefer existing and well-known tools and patterns to unproven ones for production use.
RTWReinvent The WheelWe can build it better ourselves. No matter what "it" is. We don't trust anything that was Not Invented Here.Know and use your application framework (e.g. the .NET framework). Share knowledge within your organization. Learn to make reasonable build vs. buy decisions when appropriate.

4) The Big Ball of Mud / Quagmires
Description
BBMThe Big Ball of Mud / QuagmiresSpaghetti code jungle. The overall structure of the system may never have been well defined.
Only those who are unconcerned about architecture, and, perhaps, are comfortable with the inertia of the day-to-day chore of patching the holes in these failing dikes, are content to work on such systems.
These systems show unmistakable signs of unregulated growth, and repeated, expedient repair
DescriptionPrefer
TCThrowaway CodeTaking the time to write a proper, well thought out, well documented program might take more time that is available to solve a problem, or more time that the problem meritsThe real problem with THROWAWAY CODE comes when it isn't thrown away.
SURSweeping it Under the RugIf you can't make a mess go away, ate least you can hide it.Clean up messy code. There is a limit to how much chaos an individual can tolerate before being overwhelmed.
TRTotal RewriteYour code has declined to the point where it is beyond repair, or even comprehension.Therefore, throw it away and start over. Doing a fresh draft is a way to overcome neglect. Issues are revisited. A fresh draft adds vigor. You draw back to leap. The quagmire vanishes. The swamp is drained.