0% found this document useful (1 vote)
416 views27 pages

IDesign C# Coding Standard 2.4

Guidelines writing C# code

Uploaded by

Glauco Cucchiar
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (1 vote)
416 views27 pages

IDesign C# Coding Standard 2.4

Guidelines writing C# code

Uploaded by

Glauco Cucchiar
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 27

www.idesign.

net July 2011


- 1 -
2011 IDesign Inc. All rights reserved
C# Coding Standard
Guidelines and Best Practices
Version 2.4
Author: Juval Lowy
www.idesign.net
www.idesign.net July 2011
- 2 -
2011 IDesign Inc. All rights reserved
Table oI Content
PreIace ........................................................................................................................... 3
1. Naming Conventions and Style.................................................................................. 4
2 Coding Practices ........................................................................................................ 8
3 Project Settings and Project Structure...................................................................... 16
4 Framework SpeciIic Guidelines ............................................................................... 20
4.1 Data Access....................................................................................................... 20
4.2 ASP.NET and Web Services............................................................................. 20
4.3 Multithreading................................................................................................... 21
4.4 Serialization ...................................................................................................... 23
4.5 Remoting........................................................................................................... 23
4.6 Security ............................................................................................................. 24
4.7 System.Transactions ......................................................................................... 25
4.8 Enterprise Services............................................................................................ 26
5 Resources ................................................................................................................. 27
www.idesign.net July 2011
- 3 -
2011 IDesign Inc. All rights reserved
Preface
A comprehensive coding standard is essential Ior a successIul product delivery. The
standard helps in enIorcing best practices and avoiding pitIalls, and makes knowledge
dissemination across the team easier. Traditionally, coding standards are thick, laborious
documents, spanning hundreds oI pages and detailing the rationale behind every
directive. While these are still better than no standard at all, such eIIorts are usually
indigestible by the average developer. In contrast, the C# coding standard presented here
is very thin on the 'why and very detailed on the 'what and the 'how. I believe that
while Iully understanding every insight that goes into a particular programming decision
may require reading books and even years oI experience, applying the standard should
not. When absorbing a new developer into your team, you should be able to simply point
him or her at the standard and say: "Read this Iirst." Being able to comply with a good
standard should come beIore Iully understanding and appreciating itthat should come
over time, with experience. The coding standard presented next captures best practices,
dos and don'ts, pitIalls, guidelines, and recommendations, as well as naming conventions
and styles, project settings and structure, and Iramework-speciIic guidelines. Since I Iirst
published this standard Ior C# 1.1 in 2003, it has become the de-Iacto industry standard
Ior C# and .NET development.
Juval Lowy
January 2008
www.idesign.net July 2011
- 4 -
2011 IDesign Inc. All rights reserved
1. Naming Conventions and Style
1. Use Pascal casing Ior type and method names and constants:
public class SomeClass
{
const int DefaultSize = 100;
public void SomeMethod()
{}
}
2. Use camel casing Ior local variable names and method arguments.
void MyMethod(int someNumber)
{
int number;
}
3. PreIix interIace names with I
interface IMyInterface
{...}
4. PreIix private member variables with m_. Use Pascal casing Ior the rest oI a member
variable name Iollowing the m_.
public class SomeClass
{
private int m_Number;
}
5. SuIIix custom attribute classes with Attribute.
6. SuIIix custom exception classes with Exception.
7. Name methods using verb-object pair, such as ShowDialog().
8. Methods with return values should have a name describing the value returned, such
as GetObjectState().
9. Use descriptive variable names.
a) Avoid single character variable names, such as i or t. Use index or temp
instead.
b) Avoid using Hungarian notation Ior public or protected members.
c) Do not abbreviate words (such as num instead oI number).
10. Always use C# predeIined types rather than the aliases in the System namespace.
For example:
object NOT Object
string NOT String
int NOT Int32
11. With generics, use capital letters Ior types. Reserve suIIixing Type when dealing
with the .NET type Type.
//Correct:
public class LinkedList<K,T>
{...}
//Avoid:
public class LinkedList<KeyType,DataType>
{...}
www.idesign.net July 2011
- 5 -
2011 IDesign Inc. All rights reserved
12. Use meaningIul namespaces such as the product name or the company name.
13. Avoid Iully qualiIied type names. Use the using statement instead.
14. Avoid putting a using statement inside a namespace.
15. Group all Iramework namespaces together and put custom or third-party namespaces
underneath.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using MyCompany;
using MyControls;
16. Use delegate inIerence instead oI explicit delegate instantiation.
delegate void SomeDelegate();
public void SomeMethod()
{...}
SomeDelegate someDelegate = SomeMethod;
17. Maintain strict indentation. Do not use tabs or nonstandard indentation, such as one
space. Recommended values are three or Iour spaces, and the value should be
uniIorm across.
18. Indent comments at the same level oI indentation as the code you are documenting.
19. All comments should pass spell checking. Misspelled comments indicate sloppy
development.
20. All member variables should be declared at the top, with one line separating them
Irom the properties or methods.
public class MyClass
{
int m_Number;
string m_Name;
public void SomeMethod1()
{}
public void SomeMethod2()
{}
}
21. Declare a local variable as close as possible to its Iirst use.
22. A Iile name should reIlect the class it contains.
23. When using partial types and allocating a part per Iile, name each Iile aIter the
logical part that part plays. For example:
//In MyClass.cs
public partial class MyClass
{...}
//In MyClass.Designer.cs
public partial class MyClass
{...}
24. Always place an open curly brace ({) in a new line.
www.idesign.net July 2011
- 6 -
2011 IDesign Inc. All rights reserved
25. With anonymous methods, mimic the code layout oI a regular method, aligned with
the delegate declaration. (complies with placing an open curly brace in a new line):
delegate void SomeDelegate(string someString);
//Correct:
void InvokeMethod()
{
SomeDelegate someDelegate = delegate(string name)
{
MessageBox.Show(name);
};
someDelegate("Juval");
}
//Avoid
void InvokeMethod()
{
SomeDelegate someDelegate = delegate(string name){MessageBox.Show(name);};
someDelegate("Juval");
}
26. Use empty parentheses on parameter-less anonymous methods. Omit the parentheses
only iI the anonymous method could have been used on any delegate:
delegate void SomeDelegate();
//Correct
SomeDelegate someDelegate1 = delegate()
{
MessageBox.Show("Hello");
};
//Avoid
SomeDelegate someDelegate1 = delegate
{
MessageBox.Show("Hello");
};
www.idesign.net July 2011
- 7 -
2011 IDesign Inc. All rights reserved
27. With Lambda expressions, mimic the code layout oI a regular method, aligned with
the delegate declaration. Omit the variable type and rely on type inIerence,
yet use parentheses:
delegate void SomeDelegate(string someString);
SomeDelegate someDelegate = (name)=>
{
Trace.WriteLine(name);
MessageBox.Show(name);
};
28. Only use in-line Lambda expressions when they contain a single simple statement.
Avoid multiple statements that require a curly brace or a return statement with in-
line expressions. Omit parentheses:
delegate void SomeDelegate(string someString);
void MyMethod(SomeDelegate someDelegate)
{...}
//Correct:
MyMethod(name=>MessageBox.Show(name));
//Avoid
MyMethod((name)=>{Trace.WriteLine(name);MessageBox.Show(name);});
www.idesign.net July 2011
- 8 -
2011 IDesign Inc. All rights reserved
2 Coding Practices
1. Avoid putting multiple classes in a single Iile.
2. A single Iile should contribute types to only a single namespace. Avoid having
multiple namespaces in the same Iile.
3. Avoid Iiles with more than 500 lines (excluding machine-generated code).
4. Avoid methods with more than 200 lines.
5. Avoid methods with more than 5 arguments. Use structures Ior passing multiple
arguments.
6. Lines should not exceed 120 characters.
7. Do not manually edit any machine-generated code.
a) II modiIying machine generated code, modiIy the Iormat and style to match this
coding standard.
b) Use partial classes whenever possible to Iactor out the maintained portions.
8. Avoid comments that explain the obvious. Code should be selI-explanatory. Good
code with readable variable and method names should not require comments.
9. Document only operational assumptions, algorithm insights and so on.
10. Avoid method-level documentation.
a) Use extensive external documentation Ior API documentation.
b) Use method-level comments only as tool tips Ior other developers.
11. With the exception oI zero and one, never hard-code a numeric value; always declare
a constant instead.
12. Use the const directive only on natural constants such as the number oI days oI the
week.
13. Avoid using const on read-only variables. For that, use the readonly directive.
public class MyClass
{
public const int DaysInWeek = 7;
public readonly int Number;
public MyClass(int someValue)
{
Number = someValue;
}
}
www.idesign.net July 2011
- 9 -
2011 IDesign Inc. All rights reserved
14. In general, preIer overloading to deIault parameters:
//Avoid:
class MyClass
{
void MyMethod(int number = 123)
{...}
}
//Correct:
class MyClass
{
void MyMethod()
{
MyMethod(123);
}
void MyMethod(int number)
{...}
}
15. When using deIault parameters, restrict them to natural immutable constants such as
null, Ialse, or 0:
void MyMethod(int number = 0)
{...}
void MyMethod(string name = null)
{...}
void MyMethod(bool flag = false)
{...}
16. Assert every assumption. On average, every 6
th
line is an assertion.
using System.Diagnostics;
object GetObject()
{...}
object someObject = GetObject();
Debug.Assert(someObject != null);
17. Every line oI code should be walked through in a 'white box testing manner.
18. Catch only exceptions Ior which you have explicit handling.
19. In a catch statement that throws an exception, always throw the original exception
(or another exception constructed Irom the original exception) to maintain the stack
location oI the original error:
catch(Exception exception)
{
MessageBox.Show(exception.Message);
throw;
}
20. Avoid error codes as method return values.
21. Avoid deIining custom exception classes.
22. When deIining custom exceptions:
a) Derive the custom exception Irom Exception.
b) Provide custom serialization.
www.idesign.net July 2011
- 10 -
2011 IDesign Inc. All rights reserved
23. Avoid multiple Main() methods in a single assembly.
24. Make only the most necessary types public, mark others as internal.
25. Avoid Iriend assemblies, as they increase inter-assembly coupling.
26. Avoid code that relies on an assembly running Irom a particular location.
27. Minimize code in application assemblies (EXE client assemblies). Use class libraries
instead to contain business logic.
28. Avoid providing explicit values Ior enums unless they are integer powers oI 2:
//Correct
public enum Color
{
Red,Green,Blue
}
//Avoid
public enum Color
{
Red = 1,
Green = 2,
Blue = 3
}
29. Avoid speciIying a type Ior an enum.
//Avoid
public enum Color : long
{
Red,Green,Blue
}
30. Always use a curly brace scope in an if statement, even iI it conditions a single
statement.
31. Avoid using the ternary conditional operator.
32. Avoid explicit code exclusion oI method calls (#if#endif). Use conditional
methods instead:
[Conditional("MySpecialCondition")]
public void MyMethod()
{}
33. Avoid Iunction calls in Boolean conditional statements. Assign into local variables
and check on them.
bool IsEverythingOK()
{...}
//Avoid:
if(IsEverythingOK())
{...}
//Correct:
bool ok = IsEverythingOK();
if(ok)
{...}
34. Always use zero-based arrays.
35. With indexed collection, use zero-based indexes
www.idesign.net July 2011
- 11 -
2011 IDesign Inc. All rights reserved
36. Always explicitly initialize an array oI reIerence types using a for loop.
public class MyClass
{}
const int ArraySize = 100;
MyClass[] array = new MyClass[ArraySize];
for(int index = 0; index < array.Length; index++)
{
array[index] = new MyClass();
}
37. Do not provide public or protected member variables. Use properties instead.
38. Avoid explicit properties that do nothing except access a member variable. Use
automatic properties instead:
//Avoid:
class MyClass
{
int m_Number;
public int Number
{
get
{
return m_Number;
}
set
{
m_Number = value;
}
}
}
//Correct:
class MyClass
{
public int Number
{
get;set;
}
}
39. Avoid using the new inheritance qualiIier. Use override instead.
40. Always mark public and protected methods as virtual in a non-sealed class.
41. Never use unsaIe code, except when using interop.
42. Avoid explicit casting. Use the as operator to deIensively cast to a type.
Dog dog = new GermanShepherd();
GermanShepherd shepherd = dog as GermanShepherd;
if(shepherd != null)
{...}
43. Always check a delegate Ior null beIore invoking it.
www.idesign.net July 2011
- 12 -
2011 IDesign Inc. All rights reserved
44. Do not provide public event member variables. Use event accessors instead.
public class MyPublisher
{
MyDelegate m_SomeEvent;
public event MyDelegate SomeEvent
{
add
{
m_SomeEvent += value;
}
remove
{
m_SomeEvent -= value;
}
}
}
45. Avoid deIining event-handling delegates. Use EventHandler<T> or
GenericEventHandler instead. GenericEventHandler is deIined in
Chapter 6 oI Programming .NET Components 2
nd
Edition.
46. Avoid raising events explicitly. Use EventsHelper to publish events deIensively.
EventsHelper is presented in Chapter 6-8 oI Programming .NET Components
2
nd
Edition.
47. Always use interIaces. See Chapters 1 and 3 in Programming .NET Components 2
nd
Edition.
48. Classes and interIaces should have at least 2:1 ratio oI methods to properties.
49. Avoid interIaces with one member.
50. Strive to have three to Iive members per interIace.
51. Do not have more than 20 members per interIace. Twelve is probably the practical
limit.
52. Avoid events as interIace members.
53. When using abstract classes, oIIer an interIace as well.
54. Expose interIaces on class hierarchies.
55. PreIer using explicit interIace implementation.
56. Never assume a type supports an interIace. DeIensively query Ior that interIace.
SomeType obj1;
IMyInterface obj2;
/* Some code to initialize obj1, then: */
obj2 = obj1 as IMyInterface;
if(obj2 != null)
{
obj2.Method1();
}
else
{
//Handle error in expected interface
}
57. Never hardcode strings that will be presented to end users. Use resources instead.
www.idesign.net July 2011
- 13 -
2011 IDesign Inc. All rights reserved
58. Never hardcode strings that might change based on deployment such as connection
strings.
59. Use String.Empty instead oI "":
//Avoid
string name = "";
//Correct
string name = String.Empty;
60. When building a long string, use StringBuilder, not string.
61. Avoid providing methods on structures.
a) Parameterized constructors are encouraged.
b) Can overload operators.
62. Always provide a static constructor when providing static member variables.
63. Do not use late-binding invocation when early-binding is possible.
64. Use application logging and tracing.
65. Never use goto unless in a switch statement Iall-through.
66. Always have a default case in a switch statement that asserts.
int number = SomeMethod();
switch(number)
{
case 1:
Trace.WriteLine("Case 1:");
break;
case 2:
Trace.WriteLine("Case 2:");
break;
default:
Debug.Assert(false);
break;
}
67. Do not use the this reIerence unless invoking another constructor Irom within a
constructor.
//Example of proper use of this
public class MyClass
{
public MyClass(string message)
{}
public MyClass() : this("Hello")
{}
}
www.idesign.net July 2011
- 14 -
2011 IDesign Inc. All rights reserved
68. Do not use the base word to access base class members unless you wish to resolve
a conIlict with a subclasses member oI the same name or when invoking a base class
constructor.
//Example of proper use of base
public class Dog
{
public Dog(string name)
{}
virtual public void Bark(int howLong)
{}
}
public class GermanShepherd : Dog
{
public GermanShepherd(string name): base(name)
{}
override public void Bark(int howLong)
{
base.Bark(howLong);
}
}
69. Do not use GC.AddMemoryPressure().
70. Do not rely on HandleCollector.
71. Implement Dispose() and Finalize() methods based on the template in
Chapter 4 oI Programming .NET Components 2
nd
Edition.
72. Always run code unchecked by deIault (Ior the sake oI perIormance), but explicitly
in checked mode Ior overIlow- or underIlow-prone operations:
int CalcPower(int number,int power)
{
int result = 1;
for(int count = 1;count <= power;count++)
{
checked
{
result *= number;
}
}
return result;
}
73. Avoid casting to and Irom System.Object in code that uses generics. Use
constraints or the as operator instead:
class SomeClass
{}
//Avoid:
class MyClass<T>
{
void SomeMethod(T t)
{
object temp = t;
SomeClass obj = (SomeClass)temp;
}
www.idesign.net July 2011
- 15 -
2011 IDesign Inc. All rights reserved
}
//Correct:
class MyClass<T> where T : SomeClass
{
void SomeMethod(T t)
{
SomeClass obj = t;
}
}
74. Do not deIine constraints in generic interIaces. InterIace-level constraints can oIten
be replaced by strong-typing.
public class Customer
{...}
//Avoid:
public interface IList<T> where T : Customer
{...}
//Correct:
public interface ICustomerList : IList<Customer>
{...}
75. Do not deIine method-speciIic constraints in interIaces.
76. Do not deIine constraints in delegates.
77. II a class or a method oIIers both generic and non generic Ilavors, always preIer
using the generics Ilavor.
78. When implementing a generic interIace that derives Irom an equivalent non-generic
interIace (such as IEnumerable<T>), use explicit interIace implementation on all
methods, and implement the non-generic methods by delegating to the generic ones:
class MyCollection<T> : IEnumerable<T>
{
IEnumerator<T> IEnumerable<T>.GetEnumerator()
{...}
IEnumerator IEnumerable.GetEnumerator()
{
IEnumerable<T> enumerable = this;
return enumerable.GetEnumerator();
}
}
79. Only use var when the right side oI the assignment clearly indicates the type oI the
variable:
//Avoid:
var myVariable = DoSomethig();
//Correct:
var name = EmployeeName;
80. Do not assign method return types or complex expressions into a var variable, with
the exception oI LINQ projections that result in anonymous types.
www.idesign.net July 2011
- 16 -
2011 IDesign Inc. All rights reserved
3 Project Settings and Project Structure
1. For Target Framework, always select the earliest target Iramework required Ior your
solution, unlike the deIault which will give you the latest:
2. Always build your project with warning level 4
www.idesign.net July 2011
- 17 -
2011 IDesign Inc. All rights reserved
3. Treat warnings as errors in the Release build (note that this is not the deIault oI
Visual Studio). Although it is optional, this standard recommends treating warnings
as errors in Debug builds as well.
4. Avoid suppressing speciIic compiler warnings.
5. Always explicitly state your supported runtime versions in the application
conIiguration Iile.
<?xml version="1.0"?>
<configuration>
<startup>
<supportedRuntime version="v2.0.50727.0"/>
<supportedRuntime version="v1.1.4322.0"/>
</startup>
</configuration>
6. Avoid explicit custom version redirection and binding to CLR assemblies.
7. Avoid explicit preprocessor deIinitions (#define). Use the project settings Ior
deIining conditional compilation constants.
8. Do not put any logic inside AssemblvInfo.cs.
9. Do not put any assembly attributes in any Iile besides AssemblvInfo.cs.
10. Populate all Iields in AssemblvInfo.cs such as company name, description, and
copyright notice.
11. All assembly reIerences in the same solution should use relative paths.
12. Disallow cyclic reIerences between assemblies.
www.idesign.net July 2011
- 18 -
2011 IDesign Inc. All rights reserved
13. Avoid multi-module assemblies.
14. Avoid tampering with exception handling using the Exception window
(Debug,Exceptions).
15. Strive to use uniIorm version numbers on all assemblies and clients in the same
logical application (typically a solution). Use the SolutionInfo.cs technique Irom
Chapter 5 oI Programming .NET Components 2
nd
Edition to automate.
16. Link all solution-wide inIormation to a global shared SolutionInfo.cs Iile.
17. Name your application conIiguration Iile as App.config, and include it in the project.
18. ModiIy Visual Studio 2008 deIault project structure to comply with your project
standard layout, and apply uniIorm structure Ior project Iolders and Iiles.
19. A Release build should contain debug symbols.
www.idesign.net July 2011
- 19 -
2011 IDesign Inc. All rights reserved
20. Always sign your assemblies, including the client applications.
21. Use password-protected keys.
www.idesign.net July 2011
- 20 -
2011 IDesign Inc. All rights reserved
4 Framework Specific Guidelines
4.1 Data Access
1. Always use type-saIe data sets or data tables. Avoid raw ADO.NET.
2. Always use transactions when accessing a database.
a) Always use WCF, Enterprise Services or System.Transactions transactions.
b) Do not use ADO.NET transactions by enlisting the database explicitly.
3. Always use transaction isolation level set to Serializable. Management decision is
required to use anything else.
4. Do not use the Data Source window to drop connections on windows Iorms,
ASP.NET Iorms or web services. Doing so couples the presentation tier to the data
tier.
5. Avoid SQL Server authentication. Use Windows authentication instead.
6. Run components accessing SQL Server under separate identity Irom that oI the
calling client.
7. Always wrap your stored procedures in a high level, type saIe class. Only that class
invokes the stored procedures. Let Visual Studio 2008 type-saIe data adapters
automate as much oI that as possible.
8. Avoid putting any logic inside a stored procedure. II you have anything more
complex than simple switching logic to vary your query based on the parameter
values, you should consider putting that logic in the business logic oI the consuming
code.
4.2 ASP.NET and Web Services
1. Avoid putting code in ASPX Iiles oI ASP.NET. All code should be in the code-
beside partial class.
2. Code in code beside partial class oI ASP.NET should call other components rather
than contain direct business logic.
3. Always check a session variable Ior null beIore accessing it.
4. In transactional pages or web services, always store session in SQL server.
5. Avoid setting the Auto-Postback property oI server controls in ASP.NET to True.
6. Turn on Smart Navigation Ior ASP.NET pages.
7. Strive to provide interIaces Ior web services. See Appendix A oI Programming .NET
Components 2
nd
Edition.
8. Always provide a namespace and service description Ior web services.
9. Always provide a description Ior web methods.
10. When adding a web service reIerence, provide a meaningIul name Ior the location.
www.idesign.net July 2011
- 21 -
2011 IDesign Inc. All rights reserved
11. In both ASP.NET pages and web services, wrap a session variable in a local
property. Only that property is allowed to access the session variable, and the rest oI
the code uses the property, not the session variable.
public class Calculator : WebService
{
int Memory
{
get
{
int memory = 0;
object state = Session["Memory"];
if(state != null)
{
memory = (int)state;
}
return memory;
}
set
{
Session["Memory"] = value;
}
}
[WebMethod(EnableSession=true)]
public void MemoryReset()
{
Memory = 0;
}
}
12. Always modiIy a client-side web service wrapper class to support cookies, since you
have no way oI knowing whether the service uses Session state or not.
public class Calculator : SoapHttpClientProtocol
{
public Calculator()
{
CookieContainer = new System.Net.CookieContainer();
Url = ...;
}
}
4.3 Multithreading
1. Use Synchronization Domains. See Chapter 8 in Programming .NET Components
2
nd
Edition. Avoid manual synchronization because that oIten leads to deadlocks and
race conditions.
2. Never call outside your synchronization domain.
3. Manage asynchronous call completion on a callback method. Do not wait, poll, or
block Ior completion.
4. Always name your threads. The name is traced in the debugger Threads window,
making debug sessions more productive.
Thread currentThread = Thread.CurrentThread;
string threadName = "Main UI Thread";
currentThread.Name = threadName;
www.idesign.net July 2011
- 22 -
2011 IDesign Inc. All rights reserved
5. Do not call Suspend() or Resume() on a thread.
6. Do not call Thread.Sleep(), except in the Iollowing conditions:
a) Thread.Sleep(0) is an acceptable optimization technique to Iorce a context
switch.
b) Thread.Sleep() is acceptable in testing or simulation code.
7. Do not call Thread.SpinWait().
8. Do not call Thread.Abort() to terminate threads. Use a synchronization object
instead to signal the thread to terminate. See Chapter 8 in Programming .NET
Components 2
nd
Edition.
9. Avoid explicitly setting thread priority to control execution. You can set thread
priority based on task semantic, such as below normal
(ThreadPriority.BelowNormal) Ior a screen saver.
10. Do not read the value oI the ThreadState property. Use Thread.IsAlive to
determine whether the thread is dead or alive.
11. Do not rely on setting the thread type to background thread Ior application shutdown.
Use a watchdog or other monitoring entity to deterministically kill threads.
12. Do not use thread local storage unless thread aIIinity is guaranteed.
13. Do not call Thread.MemoryBarrier().
14. Never call Thread.Join() without checking that you are not joining your own
thread.
void WaitForThreadToDie(Thread thread)
{
Debug.Assert(Thread.CurrentThread.ManagedThreadId != thread.ManagedThreadId);
thread.Join();
}
15. Always use the lock() statement rather than explicit Monitor manipulation.
16. Always encapsulate the lock() statement inside the object it protects.
public class MyClass
{
public void DoSomething()
{
lock(this)
{...}
}
}
17. You can use synchronized methods instead oI writing the lock() statement
yourselI.
18. Avoid Iragmented locking (see Chapter 8 oI Programming .NET Components 2
nd
Edition).
19. Avoid using a Monitor to wait or pulse objects. Use manual or auto-reset events
instead.
20. Do not use volatile variables. Lock your object or Iields instead to guarantee
deterministic and thread-saIe access. Do not use Thread.VolatileRead(),
Thread.VolatileWrite(), or the volatile modiIier.
www.idesign.net July 2011
- 23 -
2011 IDesign Inc. All rights reserved
21. Avoid increasing the maximum number oI threads in the thread pool.
22. Never stack lock statements because that does not provide atomic locking. Use
WaitHandle.WaitAll() instead.
MyClass obj1 = new MyClass();
MyClass obj2 = new MyClass();
MyClass obj3 = new MyClass();
//Do not stack lock statements
lock(obj1)
lock(obj2)
lock(obj3)
{
obj1.DoSomething();
obj2.DoSomething();
obj3.DoSomething();
}
4.4 Serialization
1. PreIer the binary Iormatter.
2. Mark serialization event handling methods as private.
3. Use the generic IGenericFormatter interIace. See Chapter 9 oI Programming
.NET Components 2
nd
Edition.
4. Mark non-sealed classes as serializable.
5. When implementing IDeserializationCallback on a non-sealed class,
make sure to do so in a way that allowed subclasses to call the base class
implementation oI OnDeserialization().See Chapter 3 oI Programming .NET
Components 2
nd
Edition.
6. Always mark un-serializable member variables as non serializable.
7. Always mark delegates on a serialized class as non-serializable Iields:
[Serializable]
public class MyClass
{
[field:NonSerialized]
public event EventHandler MyEvent;
}
4.5 Remoting
1. PreIer administrative conIiguration to programmatic conIiguration.
2. Always implement IDisposable on single call objects.
3. Always preIer a TCP channel and a binary Iormat when using remoting, unless a
Iirewall is present.
4. Always provide a null lease Ior a singleton object.
public class MySingleton : MarshalByRefObject
{
public override object InitializeLifetimeService()
{
return null;
}
}
www.idesign.net July 2011
- 24 -
2011 IDesign Inc. All rights reserved
5. Always provide a sponsor Ior a client activated object. The sponsor should return the
initial lease time.
6. Always unregister the sponsor on client application shutdown.
7. Always put remote objects in class libraries.
8. Avoid using SoapSuds.
9. Avoid hosting in IIS.
10. Avoid using uni-directional channels.
11. Always load a remoting conIiguration Iile in Main() even iI the Iile is empty, and
the application does not use remoting.
static void Main()
{
RemotingConfiguration.Configure("MyApp.exe.config");
/* Rest of Main() */
}
12. Avoid using Activator.GetObject() and
Activator.CreateInstance() Ior remote objects activation. Use new
instead.
13. Always register port 0 on the client side, to allow callbacks.
14. Always elevate type Iiltering to Iull on both client and host to allow callbacks.
4.6 Security
1. Always demand your own strong name on assemblies and components that are
private to the application, but are public (so that only you can use them).
public class PublicKeys
{
public const string MyCompany = "1234567894800000940000000602000000240000"+
"52534131000400000100010007D1FA57C4AED9F0"+
"A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C83"+
"4C99921EB23BE79AD9D5DCC1DD9AD23613210290"+
"0B723CF980957FC4E177108FC607774F29E8320E"+
"92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99"+
"285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF"+
"0FC4963D261C8A12436518206DC093344D5AD293";
}
[StrongNameIdentityPermission(SecurityAction.LinkDemand,
PublicKey = PublicKeys.MyCompany)]
public class MyClass
{...}
2. Apply encryption and security protection on application conIiguration Iiles.
3. When importing an interop method, assert unmanaged code permission, and demand
appropriate permission instead.
[DllImport("user32",EntryPoint="MessageBoxA")]
private static extern int Show(IntPtr handle,string text,string caption,
int msgType);
[SecurityPermission(SecurityAction.Assert,UnmanagedCode = true)]
[UIPermission(SecurityAction.Demand,
Window = UIPermissionWindow.SafeTopLevelWindows)]
www.idesign.net July 2011
- 25 -
2011 IDesign Inc. All rights reserved
public static void Show(string text,string caption)
{
Show(IntPtr.Zero,text,caption,0);
}
4. Do not suppress unmanaged code access via the
SuppressUnmanagedCodeSecurity attribute.
5. Do not use the /unsafe switch oI TlbImp.exe. Wrap the RCW in managed code so
that you could assert and demand permissions declaratively on the wrapper.
6. On server machines, deploy a code access security policy that grants only MicrosoIt,
ECMA, and selI (identiIied by a strong name) Iull trust. Code originating Irom
anywhere else is implicitly granted nothing.
7. On client machines, deploy a security policy which grants client application only the
permissions to execute, to call back the server and to potentially display user
interIace. When not using ClickOnce, client application should be identiIied by a
strong name in the code groups.
8. To counter a luring attack, always reIuse at the assembly level all permissions not
required to perIorm the task at hand.
[assembly:UIPermission(SecurityAction.RequestRefuse,
Window=UIPermissionWindow.AllWindows)]
9. Always set the principal policy in every Main() method to Windows
public class MyClass
{
static void Main()
{
AppDomain currentDomain = Thread.GetDomain();
currentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
}
//other methods
}
10. Never assert a permission without demanding a diIIerent permission in its place. See
Chapter 12 in Programming .NET Components 2
nd
Edition.
4.7 System.Transactions
1. Always dispose oI a TransactionScope object.
2. Inside a transaction scope, do not put any code aIter the call to Complete().
3. When setting the ambient transaction, always save the old ambient transaction and
restore it when you are done.
4. In Release builds, never set the transaction timeout to zero (inIinite timeout).
5. When cloning a transaction, always use
DependentCloneOption.BlockCommitUntilComplete.
6. Create a new dependent clone Ior each worker thread. Never pass the same
dependent clone to multiple threads.
7. Do not pass a transaction clone to the TransactionScope's constructor.
8. Always catch and discard exceptions thrown by a transaction scope that is set to
TransactionScopeOption.Suppress.
www.idesign.net July 2011
- 26 -
2011 IDesign Inc. All rights reserved
4.8 Enterprise Services
1. Do not catch exceptions in a transactional method. Use the AutoComplete
attribute. See Chapter 4 in COM and .NET Component Services.
2. Do not call SetComplete(), SetAbort(), and the like. Use the
AutoComplete attribute.
[Transaction]
public class MyComponent : ServicedComponent
{
[AutoComplete]
public void MyMethod(long objectIdentifier)
{...}
}
3. Always override CanBePooled and return true (unless you have a good reason
not to return to pool)
public class MyComponent : ServicedComponent
{
protected override bool CanBePooled()
{
return true;
}
}
4. Always call Dispose() explicitly on a pooled objects unless the component is
conIigured to use JITA as well.
5. Never call Dispose() when the component uses JITA.
6. Always set authorization level to application and component.
7. Set authentication level to privacy on all applications.
[assembly: ApplicationActivation(ActivationOption.Server)]
[assembly: ApplicationAccessControl(
true, //Authorization
AccessChecksLevel=AccessChecksLevelOption.ApplicationComponent,
Authentication=AuthenticationOption.Privacy,
ImpersonationLevel=ImpersonationLevelOption.Identify)]
8. Set impersonation level on client assemblies to Identity.
9. Always set ComponentAccessControl attribute on serviced components to
true (the deIault is true)
[ComponentAccessControl]
public class MyComponent : ServicedComponent
{...}
10. Always add to the Marshaler role the Everyone user
[assembly: SecurityRole("Marshaler",SetEveryoneAccess = true)]
11. Apply SecureMethod attribute to all classes requiring authentication.
[SecureMethod]
public class MyComponent : ServicedComponent
{...}
www.idesign.net July 2011
- 27 -
2011 IDesign Inc. All rights reserved
5 Resources
5.1 Programming .NET Components 2
nd
Edition
By Juval Lowy, O'Reilly 2005 ISBN: 0-596-10207-0
5.3 The IDesign Serviceware Downloads
IDesign serviceware download is a set oI original techniques, tools utilities and even
breakthroughs developed by the IDesign architects. The utilities are largely productivity-
enhancing tools, or they compensate Ior some oversight in the design oI .NET or WCF.
The demos are also used during our Master Classes to demystiIy technical points, as lab
exercises or to answer questions. The classes' attendees Iind the demos useIul not only in
class but aIter it. The demos serve as a starting point Ior new projects and as a rich
reIerence and samples source.
5.4 The Architect`s Master Class
The Architect`s Master Class is a Iive days training, and is the ultimate resource Ior the
proIessional architect. The class is conducted in the style oI a Master Class, where a
Master architect shares his experience and perspective, and interacts with the students.
The class has three parts, on process, technology and SOA, and the IDesign method.
While the class shows how to design modern systems, it sets the Iocus on the why` and
the rationale behind particular design decisions, oIten shedding light on poorly
understood aspects. You will see relevant design guidelines, best practices, and pitIalls,
and the crucial process skill required oI today`s architects. Don`t miss on this unique
opportunity to learn and improve your architecture skills with IDesign, and share our
passion Ior architecture and soItware engineering.
More at www.idesign.net

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy