We have implemented the user registration function and now want to increase the logging function. In particular, before and after the user registration, output a log respectively. We can of course modify the original business code.
Now ask two questions from another angle:
1. Team development, we are likely to not get the source code, how to increase this function.
2. This demand is to increase the log, and then add other requirements (such as exception handling), is still to change the business class it.
To sum up:
We want to do the enhancements of the class without modifying the original business code. Our design should conform to the object-oriented principle: open to expansion, closed to modification .
There are ways to do that. We try the following methods: use the adorner pattern to do the enhanced use of the class . NET proxy mode to do class enhancements use Castle to do class enhancements use Unity to do class enhancements (continued) use AUTOFAC to do class enhancements Original Business Class
Business model
Namespace Testaopbydecorator
{public
class User
{public
string Name {get; set;}
public int Id {get; set;}}}
Interface design
Namespace Testaopbydecorator
{public
interface iuserprocessor
{
void RegisterUser (user user);
}
}
Business implementation
Using System;
Namespace Testaopbydecorator
{public
class Userprocessor:iuserprocessor
{public
void RegisterUser (User user)
{
if (user = null)
{return
;
}
Console.WriteLine (String. Format ("registered with a user {0}:{1}", user.) Id, user. Name);}
}
Upper Call
Using System;
Namespace Testaopbydecorator
{
class program
{
private static user user = new User {Id = 1, Name = "Yunnan Red "};
static void Main (string[] args)
{
Register ();
Console.readkey ();
}
private static void Register ()
{
Iuserprocessor processor = new Userprocessor ();
Processor. RegisterUser (user);}}
using Castle to do class enhancements
We will use the Third-party Castle.core to do business enhancements to the original classes, first using NuGet installation.
Business Enhancement Implementation
Using System;
Using Castle.dynamicproxy;
Namespace Testaopbycastle
{public
class Userprocessorcastle:iinterceptor
{public
void Intercept ( Iinvocation invocation)
{
User user = invocation. Arguments[0] as User;
Before (user);
Invocation. Proceed ();
After (user);
}
private void after (user user)
{
Console.WriteLine ("Registered Users:") + user. Name);
private void before (user user)
{
Console.WriteLine (before registering Users:) + user. Name);}}
Methods that require the original business class are declared as virtual: virtual
Using System;
Namespace Testaopbycastle
{public
class Userprocessor:iuserprocessor
{public
virtual void RegisterUser (user user)
{
if (user = null)
{return
;
}
Console.WriteLine (String. Format ("registered with a user {0}:{1}", user.) Id, user. Name);}
}
Upper Call
Using Castle.dynamicproxy;
Using System;
Namespace Testaopbycastle
{
class program
{
private static user user = new User {Id = 1, Name = "Dianhong"};
static void Main (string[] args)
{
registerandlog ();
Console.readkey ();
}
private static void Registerandlog ()
{
Proxygenerator generator = new Proxygenerator ();
Userprocessorcastle Castle = new Userprocessorcastle ();
Iuserprocessor proxy = generator. Createclassproxy<userprocessor> (Castle);
Proxy. RegisterUser (user);}}
Compare the business presentation before and after the expansion
This approach modifies the original business class method, requiring that the display be defined as virtual and not quite compliant with the modify closure principle. But we have to be flexible in terms of actual projects.