Skip to content
Browse files

getting postsharp code samples ready for Richmond

  • Loading branch information...
1 parent 64cd208 commit 4be49f3f9823a18560f298281b7395f8be167900 mgroves committed May 18, 2011
View
2 1a-LazyLoading-Dependencies/ProductForm.Designer.cs
@@ -1,4 +1,4 @@
-namespace WindowsFormsApplication1
+namespace LazyLoadingDependencies
{
partial class ProductForm
{
View
56 1a-LazyLoading-Dependencies/ProductForm.cs
@@ -2,7 +2,7 @@
using System.Windows.Forms;
using PostSharp.Aspects;
-namespace WindowsFormsApplication1
+namespace LazyLoadingDependencies
{
public partial class ProductForm : Form
{
@@ -24,6 +24,33 @@ public ProductForm()
}
}
+ [Serializable]
+ public sealed class LoadDependencyAttribute : LocationInterceptionAspect
+ {
+ public override void OnGetValue(LocationInterceptionArgs args)
+ {
+ var form = (ProductForm)args.Instance; // this form is only used here to write to a listbox for demonstration
+
+ args.ProceedGetValue(); // this actually fetches the field and populates the args.Value
+ if (args.Value == null)
+ {
+ form.LogListBox.Items.Add("Instantiating ProductService");
+ var locationType = args.Location.LocationType;
+ var instantiation = ObjectFactory.GetInstance(locationType);
+
+ if (instantiation != null)
+ {
+ args.SetNewValue(instantiation);
+ }
+ args.ProceedGetValue();
+ }
+ else
+ {
+ form.LogListBox.Items.Add("Using a ProductService that has already been instantiated");
+ }
+ }
+ }
+
// this is just a "dummy" objectfactory
// use the IoC service locator of your choice (like StructureMap) instead
internal static class ObjectFactory
@@ -51,31 +78,4 @@ public string GetProductDescription(string productName)
return "Product: " + productName;
}
}
-
- [Serializable]
- public sealed class LoadDependencyAttribute : LocationInterceptionAspect
- {
- public override void OnGetValue(LocationInterceptionArgs args)
- {
- var form = (ProductForm) args.Instance; // this form is only used here to write to a listbox for demonstration
-
- args.ProceedGetValue(); // this actually fetches the field and populates the args.Value
- if (args.Value == null)
- {
- form.LogListBox.Items.Add("Instantiating ProductService");
- var locationType = args.Location.LocationType;
- var instantiation = ObjectFactory.GetInstance(locationType);
-
- if (instantiation != null)
- {
- args.SetNewValue(instantiation);
- }
- args.ProceedGetValue();
- }
- else
- {
- form.LogListBox.Items.Add("Using a ProductService that has already been instantiated");
- }
- }
- }
}
View
1 1a-LazyLoading-Dependencies/Program.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
+using LazyLoadingDependencies;
namespace WindowsFormsApplication1
{
View
79 1b-LazyLoading-CompileTimeInitialize/UserForm.cs
@@ -1,19 +1,25 @@
using System;
-using System.Collections.Generic;
+using System.Collections;
using System.Windows.Forms;
using PostSharp.Aspects;
using PostSharp.Extensibility;
+using PostSharp.Reflection;
using Message = PostSharp.Extensibility.Message;
namespace LazyLoading_CompileTimeInitialize
{
public partial class UserForm : Form
{
- [LazyLoad]
- private IUserService _userService;
+ [LoadDependency] private IUserService _userService;
+
+ // a non-interface
+ //[LoadDependency] DateTime invalidDependency1;
+
+ // an interface with no defined mapping
+ //[LoadDependency] IEnumerable invalidDependency2;
// I'm making this a public property only so that
- // the LazyLoadAttribute can write to it for demonstration purposes
+ // the LoadDependency can write to it for demonstration purposes
public ListBox LogListBox { get { return _logListBox; } }
public UserForm()
@@ -28,36 +34,20 @@ public UserForm()
}
}
- // another "dummy" interface and service
- // plug in your own real services/interfaces
- public interface IUserService
- {
- string AuthenticateUser(string username, string password);
- }
-
- public class UserService : IUserService
- {
- public string AuthenticateUser(string username, string password)
- {
- var r = new Random(DateTime.Now.Millisecond);
- return username + " was logged in: " + (r.NextDouble() < 0.5);
- }
- }
-
[Serializable]
- public sealed class LazyLoadAttribute : LocationInterceptionAspect
+ public sealed class LoadDependency : LocationInterceptionAspect
{
private Type _type;
- public override bool CompileTimeValidate(PostSharp.Reflection.LocationInfo locationInfo)
+ public override bool CompileTimeValidate(LocationInfo locationInfo)
{
if (!locationInfo.LocationType.IsInterface)
{
- Message.Write(SeverityType.Error, "001", "LazyLoad can only be used on Interfaces in {0}.{1}", locationInfo.DeclaringType, locationInfo.Name);
+ Message.Write(SeverityType.Error, "001", "LoadDependency can only be used on Interfaces in {0}.{1}", locationInfo.DeclaringType, locationInfo.Name);
return false;
}
- _type = DependencyMap.GetConcreteType(locationInfo.LocationType);
+ _type = ObjectFactory.GetInstanceType(locationInfo.LocationType);
if (_type == null)
{
Message.Write(SeverityType.Error, "002", "A concrete type was not found for {0}.{1}", locationInfo.DeclaringType, locationInfo.Name);
@@ -84,21 +74,42 @@ public override void OnGetValue(LocationInterceptionArgs args)
}
}
- // this DependencyMap only contains one interface<->dependency mapping
- // but more can be easily added
- public static class DependencyMap
+ // this is just a "dummy" objectfactory
+ // use the IoC service locator of your choice (like StructureMap) instead
+ internal static class ObjectFactory
{
- public static Type GetConcreteType(Type locationType)
+ public static Type GetInstanceType(Type locationType)
{
- var dict = new Dictionary<Type, Type>();
- // dict.Add(interface type, dependency type)
- dict.Add(typeof(IUserService), typeof(UserService));
-
- if (dict.ContainsKey(locationType))
+ // note that this is a very silly service locator
+ // since it returns a ProductRepository no matter
+ // what Type is passed in
+ if (locationType == typeof(IUserService))
{
- return dict[locationType];
+ return typeof(UserService);
}
return null;
}
}
+
+ // another "dummy" interface and service
+ // plug in your own real services/interfaces
+ public interface IUserService
+ {
+ string AuthenticateUser(string username, string password);
+ }
+
+ public class UserService : IUserService
+ {
+ private readonly Random _rand;
+
+ public UserService()
+ {
+ _rand = new Random(DateTime.Now.Millisecond);
+ }
+
+ public string AuthenticateUser(string username, string password)
+ {
+ return username + " was logged in: " + (_rand.NextDouble() < 0.5);
+ }
+ }
}
View
3 2-Auth/AuthService.cs
@@ -11,7 +11,8 @@ public string GetCurrentUsername()
public bool CurrentUserHasPermission(GovtForm singleForm, Permission permission)
{
- return singleForm.UserName == GetCurrentUsername();
+ var currentUser = GetCurrentUsername();
+ return singleForm.UserName == currentUser;
}
}
}
View
4 2-Auth/AuthorizeReturnValueAttribute.cs
@@ -23,9 +23,9 @@ public override void OnSuccess(MethodExecutionArgs args)
var singleForm = args.ReturnValue as GovtForm;
if (singleForm != null)
{
- if(Auth.CurrentUserHasPermission(singleForm, Permission.Read))
+ if(!Auth.CurrentUserHasPermission(singleForm, Permission.Read))
{
- MessageBox.Show("You are not authorized to view the details of that form", "Authorization Denied!");
+ MessageBox.Show("You are not authorized to view the details of that form.", "Authorization Denied!");
args.ReturnValue = null;
}
return;
View
3 2-Auth/GovtFormService.cs
@@ -15,6 +15,7 @@ public GovtFormService()
_govtFormsDatabase.Add(new GovtForm { FormInformation = "steve smith's form details", UserName = "ssmith"});
_govtFormsDatabase.Add(new GovtForm { FormInformation = "text of Susie Q's form information and details", UserName = "susieq"});
_govtFormsDatabase.Add(new GovtForm { FormInformation = "Walter Mathau's form information details", UserName = "wmathau" });
+ _govtFormsDatabase.Add(new GovtForm { FormInformation = "Ali Groves's form information details", UserName = "agroves" });
}
public void SubmitForm(GovtForm form)
@@ -29,7 +30,7 @@ public IEnumerable<GovtForm> GetAllForms()
return _govtFormsDatabase;
}
- [AuthorizeReturnValue]
+ //[AuthorizeReturnValue]
public GovtForm GetFormById(Guid guid)
{
return _govtFormsDatabase.FirstOrDefault(form => form.FormId == guid);
View
7 2-Auth/MainGovernmentForm.cs
@@ -15,6 +15,13 @@ public MainGovernmentForm()
InitializeComponent();
RefreshGovtForms();
+
+ PutCurrentUserNameInTitleBar();
+ }
+
+ void PutCurrentUserNameInTitleBar()
+ {
+ this.Text = "You are logged in as: " + Auth.GetCurrentUsername();
}
private void RefreshGovtForms()
View
1 3-LoggingAuditing/BankAccountManager.cs
@@ -19,7 +19,6 @@ private void depositButton_Click(object sender, EventArgs e)
RefreshBalance();
}
- [TransactionAudit]
private void withdrawlButton_Click(object sender, EventArgs e)
{
BankAccount.Withdrawl(decimal.Parse(this.amountTextbox.Text));
View
22 3-LoggingAuditing/TransactionAuditAttribute.cs
@@ -12,17 +12,6 @@ public class TransactionAuditAttribute : OnMethodBoundaryAspect
private Type _className;
private int _amountParameterIndex = -1;
- public override bool CompileTimeValidate(MethodBase method)
- {
- if(_amountParameterIndex == -1)
- {
- Message.Write(SeverityType.Warning, "999",
- "TransactionAudit was unable to find an 'amount' to audit in {0}.{1}", _className, _methodName);
- return false;
- }
- return true;
- }
-
public override void CompileTimeInitialize(MethodBase method, AspectInfo aspectInfo)
{
_methodName = method.Name;
@@ -38,6 +27,17 @@ public override void CompileTimeInitialize(MethodBase method, AspectInfo aspectI
}
}
+ public override bool CompileTimeValidate(MethodBase method)
+ {
+ if (_amountParameterIndex == -1)
+ {
+ Message.Write(SeverityType.Warning, "999",
+ "TransactionAudit was unable to find an 'amount' to audit in {0}.{1}", _className, _methodName);
+ return false;
+ }
+ return true;
+ }
+
public override void OnEntry(MethodExecutionArgs args)
{
if (_amountParameterIndex != -1)
View
26 4-Caching/CacheAttribute.cs
@@ -27,11 +27,6 @@ static CacheAttribute()
}
}
- public override void RuntimeInitialize(MethodBase method)
- {
- syncRoot = new object();
- }
-
public override void CompileTimeInitialize(MethodBase method, AspectInfo aspectInfo)
{
_methodName = method.Name;
@@ -55,15 +50,9 @@ public override bool CompileTimeValidate(MethodBase method)
return true;
}
- private static readonly IList<Type> DisallowedTypes = new List<Type>
- {
- typeof (Stream),
- typeof (IEnumerable),
- typeof (IQueryable)
- };
- private static bool IsDisallowedCacheReturnType(Type returnType)
+ public override void RuntimeInitialize(MethodBase method)
{
- return DisallowedTypes.Any(t => t.IsAssignableFrom(returnType));
+ syncRoot = new object();
}
public override void OnInvoke(MethodInterceptionArgs args)
@@ -101,5 +90,16 @@ private string BuildCacheKey(Arguments arguments)
}
return sb.ToString();
}
+
+ private static readonly IList<Type> DisallowedTypes = new List<Type>
+ {
+ typeof (Stream),
+ typeof (IEnumerable),
+ typeof (IQueryable)
+ };
+ private static bool IsDisallowedCacheReturnType(Type returnType)
+ {
+ return DisallowedTypes.Any(t => t.IsAssignableFrom(returnType));
+ }
}
}
View
1 5-TransactionManagement/5-TransactionManagement.csproj
@@ -63,7 +63,6 @@
<Compile Include="LogService.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
- <Compile Include="TransactionBoundaryScopeAttribute.cs" />
<Compile Include="TransactionScopeAttribute.cs" />
<EmbeddedResource Include="CharityManager.resx">
<DependentUpon>CharityManager.cs</DependentUpon>
View
6 5-TransactionManagement/CharityService.cs
@@ -9,11 +9,13 @@ public class CharityService : ICharityService
{
private ILogService _logService;
private readonly IList<Charity> _charityDatabase;
+ private Random _rand;
public CharityService()
{
_charityDatabase = PreprogrammedCharities.ToList();
_logService = new LogService();
+ _rand = new Random(DateTime.Now.Millisecond);
}
// since we're not hooked up to a real data layer, these are just standins for demonstration
@@ -46,9 +48,9 @@ public void UpdateACharity()
_charityDatabase[0].Name = PreprogrammedCharities.First().Name + " " + DateTime.Now.Millisecond;
}
- private static void SimulateUnreliableService()
+ private void SimulateUnreliableService()
{
- var rand = (new Random(DateTime.Now.Millisecond)).Next(0, 50);
+ var rand = (_rand.Next(0, 50));
if (rand == 2)
{
throw new Exception("Some unknown exception");
View
44 5-TransactionManagement/TransactionBoundaryScopeAttribute.cs
@@ -1,44 +0,0 @@
-using System;
-using PostSharp.Aspects;
-
-namespace TransactionManagement
-{
- [Serializable]
- public class TransactionBoundaryScopeAttribute : OnMethodBoundaryAspect
- {
- [NonSerialized] private ICharityService _charityService;
- private string _methodName;
- private string _className;
-
- public override void CompileTimeInitialize(System.Reflection.MethodBase method, AspectInfo aspectInfo)
- {
- _className = method.DeclaringType.Name;
- _methodName = method.Name;
- }
-
- public override void RuntimeInitialize(System.Reflection.MethodBase method)
- {
- // in practice, the begin/rollback/commit might be in a more general service
- // but for convenience in this demo, they reside in CharityService alongside
- // the normal repository methods
- _charityService = new CharityService();
- }
-
- public override void OnEntry(MethodExecutionArgs args)
- {
- _charityService.BeginTransaction();
- }
-
- public override void OnException(MethodExecutionArgs args)
- {
- _charityService.RollbackTransaction();
- var loggingMessage = string.Format("exception in {0}.{1}", _className, _methodName);
- // do some logging
- }
-
- public override void OnSuccess(MethodExecutionArgs args)
- {
- _charityService.CommitTransaction();
- }
- }
-}
View
92 6-Threading/6-Threading.csproj
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
+ <ProductVersion>8.0.30703</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{A326BB7E-E04F-4002-BB0A-A6A7FDDC763B}</ProjectGuid>
+ <OutputType>WinExe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Threading</RootNamespace>
+ <AssemblyName>Threading</AssemblyName>
+ <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+ <TargetFrameworkProfile>Client</TargetFrameworkProfile>
+ <FileAlignment>512</FileAlignment>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+ <PlatformTarget>x86</PlatformTarget>
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+ <PlatformTarget>x86</PlatformTarget>
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="PostSharp, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b13fd38b8f9c99d7, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\libs\PostSharp.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="Microsoft.CSharp" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Deployment" />
+ <Reference Include="System.Drawing" />
+ <Reference Include="System.Windows.Forms" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="EasyThreading.cs">
+ <SubType>Form</SubType>
+ </Compile>
+ <Compile Include="EasyThreading.Designer.cs">
+ <DependentUpon>EasyThreading.cs</DependentUpon>
+ </Compile>
+ <Compile Include="Program.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <EmbeddedResource Include="EasyThreading.resx">
+ <DependentUpon>EasyThreading.cs</DependentUpon>
+ </EmbeddedResource>
+ <EmbeddedResource Include="Properties\Resources.resx">
+ <Generator>ResXFileCodeGenerator</Generator>
+ <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+ <SubType>Designer</SubType>
+ </EmbeddedResource>
+ <Compile Include="Properties\Resources.Designer.cs">
+ <AutoGen>True</AutoGen>
+ <DependentUpon>Resources.resx</DependentUpon>
+ <DesignTime>True</DesignTime>
+ </Compile>
+ <None Include="Properties\Settings.settings">
+ <Generator>SettingsSingleFileGenerator</Generator>
+ <LastGenOutput>Settings.Designer.cs</LastGenOutput>
+ </None>
+ <Compile Include="Properties\Settings.Designer.cs">
+ <AutoGen>True</AutoGen>
+ <DependentUpon>Settings.settings</DependentUpon>
+ <DesignTimeSharedInput>True</DesignTimeSharedInput>
+ </Compile>
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
View
95 6-Threading/EasyThreading.Designer.cs
@@ -0,0 +1,95 @@
+namespace Threading
+{
+ partial class EasyThreading
+ {
+ /// <summary>
+ /// Required designer variable.
+ /// </summary>
+ private System.ComponentModel.IContainer components = null;
+
+ /// <summary>
+ /// Clean up any resources being used.
+ /// </summary>
+ /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ /// <summary>
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ /// </summary>
+ private void InitializeComponent()
+ {
+ this.listBox1 = new System.Windows.Forms.ListBox();
+ this.button1 = new System.Windows.Forms.Button();
+ this.button2 = new System.Windows.Forms.Button();
+ this.button3 = new System.Windows.Forms.Button();
+ this.SuspendLayout();
+ //
+ // listBox1
+ //
+ this.listBox1.FormattingEnabled = true;
+ this.listBox1.Location = new System.Drawing.Point(239, 24);
+ this.listBox1.Name = "listBox1";
+ this.listBox1.Size = new System.Drawing.Size(190, 264);
+ this.listBox1.TabIndex = 0;
+ //
+ // button1
+ //
+ this.button1.Location = new System.Drawing.Point(45, 85);
+ this.button1.Name = "button1";
+ this.button1.Size = new System.Drawing.Size(75, 23);
+ this.button1.TabIndex = 1;
+ this.button1.Text = "button1";
+ this.button1.UseVisualStyleBackColor = true;
+ //
+ // button2
+ //
+ this.button2.Location = new System.Drawing.Point(45, 124);
+ this.button2.Name = "button2";
+ this.button2.Size = new System.Drawing.Size(75, 23);
+ this.button2.TabIndex = 2;
+ this.button2.Text = "button2";
+ this.button2.UseVisualStyleBackColor = true;
+ //
+ // button3
+ //
+ this.button3.Location = new System.Drawing.Point(45, 165);
+ this.button3.Name = "button3";
+ this.button3.Size = new System.Drawing.Size(75, 23);
+ this.button3.TabIndex = 3;
+ this.button3.Text = "button3";
+ this.button3.UseVisualStyleBackColor = true;
+ //
+ // EasyThreading
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(441, 318);
+ this.Controls.Add(this.button3);
+ this.Controls.Add(this.button2);
+ this.Controls.Add(this.button1);
+ this.Controls.Add(this.listBox1);
+ this.Name = "EasyThreading";
+ this.Text = "EasyThreading";
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.ListBox listBox1;
+ private System.Windows.Forms.Button button1;
+ private System.Windows.Forms.Button button2;
+ private System.Windows.Forms.Button button3;
+ }
+}
+
View
88 6-Threading/EasyThreading.cs
@@ -0,0 +1,88 @@
+using System;
+using System.Reflection;
+using System.Threading;
+using System.Windows.Forms;
+using PostSharp.Aspects;
+using PostSharp.Extensibility;
+using Message = PostSharp.Extensibility.Message;
+
+namespace Threading
+{
+ public partial class EasyThreading : Form
+ {
+ public EasyThreading()
+ {
+ InitializeComponent();
+
+ BackgroundMessages();
+ BackgroundMessages();
+ BackgroundMessages();
+ BackgroundMessages();
+ BackgroundMessages();
+
+ button1.Click+=new EventHandler(button_Click);
+ button2.Click+=new EventHandler(button_Click);
+ button3.Click+=new EventHandler(button_Click);
+ }
+
+ [WorkerThread]
+ private void BackgroundMessages()
+ {
+ var rand = new Random(DateTime.Now.Millisecond);
+ while(true)
+ {
+ var sleepyTime = rand.Next(100, 1000);
+ Thread.Sleep(sleepyTime);
+ WriteMessageToListView("slept for " + sleepyTime + "ms");
+ }
+ }
+
+ [UiThread]
+ private void WriteMessageToListView(string message)
+ {
+ listBox1.Items.Add(message);
+ }
+
+ private void button_Click(object sender, EventArgs e)
+ {
+ var button = (Button) sender;
+ button.Text = DateTime.Now.TimeOfDay.ToString();
+ }
+ }
+
+ [Serializable]
+ public class WorkerThread : MethodInterceptionAspect
+ {
+ public override void OnInvoke(MethodInterceptionArgs args)
+ {
+ ThreadPool.QueueUserWorkItem(d => args.Invoke(args.Arguments));
+ }
+ }
+
+ [Serializable]
+ public class UiThread : MethodInterceptionAspect
+ {
+ public override bool CompileTimeValidate(MethodBase method)
+ {
+ if (!typeof(Form).IsAssignableFrom(method.DeclaringType))
+ {
+ Message.Write(SeverityType.Error, "003", "UiThread can only be used on methods in a Form class in {0}.{1}", method.DeclaringType.BaseType, method.Name);
+ return false;
+ }
+ return true;
+ }
+
+ public override void OnInvoke(MethodInterceptionArgs args)
+ {
+ var dispatcher = (Form) args.Instance;
+ if (dispatcher.InvokeRequired)
+ {
+ args.Proceed();
+ }
+ else
+ {
+ dispatcher.Invoke(new Action(args.Proceed));
+ }
+ }
+ }
+}
View
120 6-Threading/EasyThreading.resx
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+ <!--
+ Microsoft ResX Schema
+
+ Version 2.0
+
+ The primary goals of this format is to allow a simple XML format
+ that is mostly human readable. The generation and parsing of the
+ various data types are done through the TypeConverter classes
+ associated with the data types.
+
+ Example:
+
+ ... ado.net/XML headers & schema ...
+ <resheader name="resmimetype">text/microsoft-resx</resheader>
+ <resheader name="version">2.0</resheader>
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+ <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+ <value>[base64 mime encoded serialized .NET Framework object]</value>
+ </data>
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+ <comment>This is a comment</comment>
+ </data>
+
+ There are any number of "resheader" rows that contain simple
+ name/value pairs.
+
+ Each data row contains a name, and value. The row also contains a
+ type or mimetype. Type corresponds to a .NET class that support
+ text/value conversion through the TypeConverter architecture.
+ Classes that don't support this are serialized and stored with the
+ mimetype set.
+
+ The mimetype is used for serialized objects, and tells the
+ ResXResourceReader how to depersist the object. This is currently not
+ extensible. For a given mimetype the value must be set accordingly:
+
+ Note - application/x-microsoft.net.object.binary.base64 is the format
+ that the ResXResourceWriter will generate, however the reader can
+ read any of the formats listed below.
+
+ mimetype: application/x-microsoft.net.object.binary.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.soap.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.bytearray.base64
+ value : The object must be serialized into a byte array
+ : using a System.ComponentModel.TypeConverter
+ : and then encoded with base64 encoding.
+ -->
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+ <xsd:element name="root" msdata:IsDataSet="true">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:element name="metadata">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" use="required" type="xsd:string" />
+ <xsd:attribute name="type" type="xsd:string" />
+ <xsd:attribute name="mimetype" type="xsd:string" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="assembly">
+ <xsd:complexType>
+ <xsd:attribute name="alias" type="xsd:string" />
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="data">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="resheader">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <resheader name="resmimetype">
+ <value>text/microsoft-resx</value>
+ </resheader>
+ <resheader name="version">
+ <value>2.0</value>
+ </resheader>
+ <resheader name="reader">
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <resheader name="writer">
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+</root>
View
22 6-Threading/Program.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Windows.Forms;
+using Threading;
+
+namespace _6_Threading
+{
+ static class Program
+ {
+ /// <summary>
+ /// The main entry point for the application.
+ /// </summary>
+ [STAThread]
+ static void Main()
+ {
+ Application.EnableVisualStyles();
+ Application.SetCompatibleTextRenderingDefault(false);
+ Application.Run(new EasyThreading());
+ }
+ }
+}
View
36 6-Threading/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("6-Threading")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Microsoft")]
+[assembly: AssemblyProduct("6-Threading")]
+[assembly: AssemblyCopyright("Copyright © Microsoft 2011")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("034e004a-ad02-4e5a-82f1-87c641f6659c")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
View
63 6-Threading/Properties/Resources.Designer.cs
@@ -0,0 +1,63 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.225
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace Threading.Properties {
+ using System;
+
+
+ /// <summary>
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ /// </summary>
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources() {
+ }
+
+ /// <summary>
+ /// Returns the cached ResourceManager instance used by this class.
+ /// </summary>
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager {
+ get {
+ if (object.ReferenceEquals(resourceMan, null)) {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Threading.Properties.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ /// <summary>
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ /// </summary>
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture {
+ get {
+ return resourceCulture;
+ }
+ set {
+ resourceCulture = value;
+ }
+ }
+ }
+}
View
117 6-Threading/Properties/Resources.resx
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+ <!--
+ Microsoft ResX Schema
+
+ Version 2.0
+
+ The primary goals of this format is to allow a simple XML format
+ that is mostly human readable. The generation and parsing of the
+ various data types are done through the TypeConverter classes
+ associated with the data types.
+
+ Example:
+
+ ... ado.net/XML headers & schema ...
+ <resheader name="resmimetype">text/microsoft-resx</resheader>
+ <resheader name="version">2.0</resheader>
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+ <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+ <value>[base64 mime encoded serialized .NET Framework object]</value>
+ </data>
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+ <comment>This is a comment</comment>
+ </data>
+
+ There are any number of "resheader" rows that contain simple
+ name/value pairs.
+
+ Each data row contains a name, and value. The row also contains a
+ type or mimetype. Type corresponds to a .NET class that support
+ text/value conversion through the TypeConverter architecture.
+ Classes that don't support this are serialized and stored with the
+ mimetype set.
+
+ The mimetype is used for serialized objects, and tells the
+ ResXResourceReader how to depersist the object. This is currently not
+ extensible. For a given mimetype the value must be set accordingly:
+
+ Note - application/x-microsoft.net.object.binary.base64 is the format
+ that the ResXResourceWriter will generate, however the reader can
+ read any of the formats listed below.
+
+ mimetype: application/x-microsoft.net.object.binary.base64
+ value : The object must be serialized with
+ : System.Serialization.Formatters.Binary.BinaryFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.soap.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.bytearray.base64
+ value : The object must be serialized into a byte array
+ : using a System.ComponentModel.TypeConverter
+ : and then encoded with base64 encoding.
+ -->
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+ <xsd:element name="root" msdata:IsDataSet="true">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:element name="metadata">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" />
+ <xsd:attribute name="type" type="xsd:string" />
+ <xsd:attribute name="mimetype" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="assembly">
+ <xsd:complexType>
+ <xsd:attribute name="alias" type="xsd:string" />
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="data">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="resheader">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <resheader name="resmimetype">
+ <value>text/microsoft-resx</value>
+ </resheader>
+ <resheader name="version">
+ <value>2.0</value>
+ </resheader>
+ <resheader name="reader">
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <resheader name="writer">
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+</root>
View
26 6-Threading/Properties/Settings.Designer.cs
@@ -0,0 +1,26 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.225
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace Threading.Properties {
+
+
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")]
+ internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
+
+ private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+ public static Settings Default {
+ get {
+ return defaultInstance;
+ }
+ }
+ }
+}
View
7 6-Threading/Properties/Settings.settings
@@ -0,0 +1,7 @@
+<?xml version='1.0' encoding='utf-8'?>
+<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
+ <Profiles>
+ <Profile Name="(Default)" />
+ </Profiles>
+ <Settings />
+</SettingsFile>
View
12 Postsharp5.sln
@@ -18,6 +18,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "libs", "libs", "{FD97FE6A-D
libs\PostSharp.dll = libs\PostSharp.dll
EndProjectSection
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "6-Threading", "6-Threading\6-Threading.csproj", "{A326BB7E-E04F-4002-BB0A-A6A7FDDC763B}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -88,6 +90,16 @@ Global
{2ECCB8A8-6693-4910-8A41-6C7A033CA42E}.Release|Mixed Platforms.Build.0 = Release|x86
{2ECCB8A8-6693-4910-8A41-6C7A033CA42E}.Release|x86.ActiveCfg = Release|x86
{2ECCB8A8-6693-4910-8A41-6C7A033CA42E}.Release|x86.Build.0 = Release|x86
+ {A326BB7E-E04F-4002-BB0A-A6A7FDDC763B}.Debug|Any CPU.ActiveCfg = Debug|x86
+ {A326BB7E-E04F-4002-BB0A-A6A7FDDC763B}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
+ {A326BB7E-E04F-4002-BB0A-A6A7FDDC763B}.Debug|Mixed Platforms.Build.0 = Debug|x86
+ {A326BB7E-E04F-4002-BB0A-A6A7FDDC763B}.Debug|x86.ActiveCfg = Debug|x86
+ {A326BB7E-E04F-4002-BB0A-A6A7FDDC763B}.Debug|x86.Build.0 = Debug|x86
+ {A326BB7E-E04F-4002-BB0A-A6A7FDDC763B}.Release|Any CPU.ActiveCfg = Release|x86
+ {A326BB7E-E04F-4002-BB0A-A6A7FDDC763B}.Release|Mixed Platforms.ActiveCfg = Release|x86
+ {A326BB7E-E04F-4002-BB0A-A6A7FDDC763B}.Release|Mixed Platforms.Build.0 = Release|x86
+ {A326BB7E-E04F-4002-BB0A-A6A7FDDC763B}.Release|x86.ActiveCfg = Release|x86
+ {A326BB7E-E04F-4002-BB0A-A6A7FDDC763B}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

0 comments on commit 4be49f3

Please sign in to comment.
Something went wrong with that request. Please try again.