Skip to content

Commit

Permalink
2012-07-07 Proxy Objects post: http://www.ipreferjim.com/2012/07/prox…
Browse files Browse the repository at this point in the history
  • Loading branch information
jimschubert committed Jul 7, 2012
1 parent 99a1f3c commit ef4a1dc
Show file tree
Hide file tree
Showing 26 changed files with 14,318 additions and 0 deletions.
27 changes: 27 additions & 0 deletions 2012-07-07/Proxies/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using System.Reflection;
using System.Runtime.CompilerServices;

// Information about this assembly is defined by the following attributes.
// Change them to the values specific to your project.

[assembly: AssemblyTitle("Proxies")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("")]
[assembly: AssemblyCopyright("jim")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
// The form "{Major}.{Minor}.*" will automatically update the build and revision,
// and "{Major}.{Minor}.{Build}.*" will update just the revision.

[assembly: AssemblyVersion("1.0.*")]

// The following attributes are used to specify the signing key for the assembly,
// if desired. See the Mono documentation for more information about signing.

//[assembly: AssemblyDelaySign(false)]
//[assembly: AssemblyKeyFile("")]

41 changes: 41 additions & 0 deletions 2012-07-07/Proxies/Foo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
using System;
using System.IO;

namespace Proxies
{
public interface IFoo: ILogger {
ILogger Logger {get;set;}
string ShowBar();
}

/// <summary>
/// Foo. This class represents a simple proxy object using DI.
/// <remarks>Requries ILogger instance</remarks>
/// </summary>
public class Foo : IFoo
{
public ILogger Logger {
get;
set;
}

public Foo() { }
public Foo (ILogger logger)
{
Logger = logger;
}

public virtual void Write(string msg) {
Logger.Write(msg);
}

public string ShowBar() {
return "Bar";
}

public string ShowBaz() {
return "Baz";
}
}
}

17 changes: 17 additions & 0 deletions 2012-07-07/Proxies/FooClassProxy.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System;

namespace Proxies
{
public class FooClassProxy : Foo
{
public FooClassProxy (ILogger logger) : base(logger)
{
}

public override void Write (string msg)
{
base.Write (String.Format("Message: {0}\n", msg));
}
}
}

41 changes: 41 additions & 0 deletions 2012-07-07/Proxies/FooInterfaceProxy.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
using System;
using System.IO;

namespace Proxies
{
/// <summary>
/// Concrete foo proxy. This is interface-based proxying.
/// i.e. FooInterfaceProxy "is a" Foo and proxies Foo.Write by overriding the virtual method Write.
/// </summary>
public class FooInterfaceProxy : IFoo {
private IFoo _foo;

public ILogger Logger {
get;
set;
}

public FooInterfaceProxy(ILogger logger)
{
Logger = logger;
}

public void Write (string msg)
{
Logger.Write("Trace: FooInterfaceProxy.Write enter.");
if(_foo == null) {
Logger.Write("Trace: Creating new Foo");
_foo = new Foo(Logger);
}
_foo.Write(msg);
Logger.Write("Trace: FooInterfaceProxy.Write exit.\n");
}

public string ShowBar() {
if(_foo == null) {
throw new InvalidOperationException("FooBar :(");
}
return _foo.ShowBar();
}
}
}
33 changes: 33 additions & 0 deletions 2012-07-07/Proxies/Logger.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using System;
using System.IO;

namespace Proxies
{
public interface ILogger {
void Write(string msg);
}

/// <summary>
/// Logger. This class represents a simple wrapper object.
/// <para>
/// Logger proxies calls to TextWriter.WriteLine via the Write method,
/// but Logger is technically *not* a proxy object because it is not a TextWriter.
/// </para>
/// <remarks>Requires a TextWriter instance to write to</remarks>
/// </summary>
public class Logger : ILogger
{
public TextWriter Writer {
get;
set;
}

public Logger(TextWriter writer) {
Writer = writer;
}

public virtual void Write(string msg) {
Writer.WriteLine(msg);
}
}
}
60 changes: 60 additions & 0 deletions 2012-07-07/Proxies/Main.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
using System;
using Castle.DynamicProxy;
using System.Diagnostics;

namespace Proxies
{
class MainClass
{
public static void Main (string[] args)
{
// Add Console.Out as a listener for Debug.WriteLine to show in Mono
Debug.Listeners.Add( new ConsoleTraceListener(useErrorStream: false) );

// Using dependency injection to specify output stream
// i.e. Foo proxies ILogger
ILogger logger = new Logger (Console.Out);
Foo foo = new Foo (logger);
foo.Write ("Testing Foo\n");

Console.WriteLine("Hard-coded proxy object demonstrating trace logging:");
// You could create a second foo type which appears to be IFoo
// but actually traces method enter/exit by proxy
IFoo foo2 = new FooInterfaceProxy (logger);
foo2.Write ("Testing FooInterfaceProxy #1");
foo2.Write ("Testing FooInterfaceProxy #2");

Console.WriteLine("Hard-coded proxy object demonstrating added functionality:");
IFoo foo3 = new FooClassProxy(logger);
foo3.Write("Testing FooClassProxy");

Console.WriteLine("Dynamically proxy an existing object's virtual members (any object works):");
var proxify = new ProxyGenerator();
var interceptors = new IInterceptor[] { new DebugLogger() };
Foo foo4 = proxify.CreateClassProxyWithTarget(foo, interceptors);
foo4.Write("Class Foo proxied dynamically using CreateClassProxyWithTarget");
Console.WriteLine("Calling Class Foo's ToString(): {0}", foo4.ToString());
Console.WriteLine("Calling IFoo.ShowBar(): {0}", foo4.ShowBar());
Console.WriteLine("Calling Foo.ShowBaz(): {0}\n", foo4.ShowBaz());

Console.WriteLine ("Dynamic Proxy a specific target:");
IFoo foo5 = (IFoo)proxify.CreateInterfaceProxyWithTarget(typeof(IFoo), foo, interceptors);
foo5.Write("Class Foo proxied dynamically using CreateInterfaceProxyWithTarget");
Console.WriteLine("Calling Class Foo's ToString(): {0}\n", foo5.ToString());
Console.WriteLine("Calling IFoo.ShowBar(): {0}", foo5.ShowBar());
Console.WriteLine("Notice the order of interception above.");
}

public class DebugLogger : IInterceptor
{
#region IInterceptor implementation
public void Intercept (IInvocation invocation)
{
Debug.WriteLine("Debug: proxy enter.");
invocation.Proceed();
Debug.WriteLine("Debug: proxy exit.");
}
#endregion
}
}
}
48 changes: 48 additions & 0 deletions 2012-07-07/Proxies/Proxies.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProductVersion>10.0.0</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{3F63B14B-482E-44AC-B045-DDD710EAE270}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>Proxies</RootNamespace>
<AssemblyName>Proxies</AssemblyName>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<DebugSymbols>True</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>False</Optimize>
<OutputPath>bin\Debug</OutputPath>
<DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>x86</PlatformTarget>
<Externalconsole>True</Externalconsole>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<DebugType>none</DebugType>
<Optimize>True</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>x86</PlatformTarget>
<Externalconsole>True</Externalconsole>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="Castle.Core">
<HintPath>..\..\deps\Castle3.0\Castle.Core.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Main.cs" />
<Compile Include="AssemblyInfo.cs" />
<Compile Include="Foo.cs" />
<Compile Include="Logger.cs" />
<Compile Include="FooInterfaceProxy.cs" />
<Compile Include="FooClassProxy.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project>
20 changes: 20 additions & 0 deletions 2012-07-07/Proxies/Proxies.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Proxies", "Proxies.csproj", "{3F63B14B-482E-44AC-B045-DDD710EAE270}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x86 = Debug|x86
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{3F63B14B-482E-44AC-B045-DDD710EAE270}.Debug|x86.ActiveCfg = Debug|x86
{3F63B14B-482E-44AC-B045-DDD710EAE270}.Debug|x86.Build.0 = Debug|x86
{3F63B14B-482E-44AC-B045-DDD710EAE270}.Release|x86.ActiveCfg = Release|x86
{3F63B14B-482E-44AC-B045-DDD710EAE270}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(MonoDevelopProperties) = preSolution
StartupItem = Proxies.csproj
EndGlobalSection
EndGlobal
Binary file added deps/Castle3.0/Castle.Core.dll
Binary file not shown.
Loading

0 comments on commit ef4a1dc

Please sign in to comment.