Skip to content

Commit 721875a

Browse files
committed
decorator & proxy
1 parent e4f9563 commit 721875a

File tree

9 files changed

+366
-1
lines changed

9 files changed

+366
-1
lines changed

README.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,20 @@ This repository is a collection of my one off tutorials about asp.net core tooki
44
Full Playlist can be found [here](https://www.youtube.com/playlist?list=PLOeFnOV9YBa4ary9fvCULLn7ohNKR6Ees).
55

66
## Table of contents
7+
8+
### Creational Patterns
9+
710
- [Factory, Abstract Factory, Factory Method](https://youtu.be/xN7EFHU_rXA)
811
- [Builder](https://youtu.be/WfBsYo20D_I)
912
- [Prototype](https://youtu.be/fqaoCDyxb1w)
1013
- [Singleton](https://youtu.be/9_9hI69fwhg)
11-
- [Adapter](https://youtu.be/9ZFN8DrvcYA)
14+
15+
### Structural Patterns
16+
17+
- [Adapter](https://youtu.be/9ZFN8DrvcYA)
18+
- [Decorator](https://youtu.be/6rTnCkdbJA4)
19+
- [Proxy](https://youtu.be/m0aXyRDEQqU)
20+
21+
22+
### Behavioral Patterns
23+
WIP
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<Query Kind="Program">
2+
<NuGetReference>Microsoft.Extensions.Caching.Abstractions</NuGetReference>
3+
<Namespace>Microsoft.Extensions.Caching.Distributed</Namespace>
4+
<Namespace>System.Threading.Tasks</Namespace>
5+
</Query>
6+
7+
void Main()
8+
{
9+
10+
}
11+
12+
public class KeyPrefixedCache : IDistributedCache
13+
{
14+
IDistributedCache _cache;
15+
string _prefix;
16+
17+
public KeyPrefixedCache(IDistributedCache cache, string prefix)
18+
{
19+
_cache = cache;
20+
_prefix = prefix;
21+
}
22+
23+
private string PrefixKey(string key) => $"{_prefix}_{key}";
24+
25+
public byte[] Get(string key) =>
26+
_cache.Get(PrefixKey(key));
27+
28+
public Task<byte[]> GetAsync(string key, CancellationToken token = default) =>
29+
_cache.GetAsync(PrefixKey(key), token)
30+
31+
public void Refresh(string key) =>
32+
_cache.Refresh(PrefixKey(key));
33+
34+
public Task RefreshAsync(string key, CancellationToken token = default) =>
35+
_cache.RefreshAsync(PrefixKey(key), token);
36+
37+
public void Remove(string key) =>
38+
_cache.Remove(PrefixKey(key));
39+
40+
public Task RemoveAsync(string key, CancellationToken token = default) =>
41+
_cache.RemoveAsync(PrefixKey(key), token)
42+
43+
public void Set(string key, byte[] value, DistributedCacheEntryOptions options) =>
44+
_cache.Set(PrefixKey(key), value, options);
45+
46+
public Task SetAsync(string key, byte[] value, DistributedCacheEntryOptions options, CancellationToken token = default) =>
47+
_cache.SetAsync(PrefixKey(key), value, options, token);
48+
}

decorator/example.linq

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<Query Kind="Program" />
2+
3+
void Main()
4+
{
5+
6+
}
7+
8+
public interface IDumbData
9+
{
10+
int Id { get; set; }
11+
string Name { get; set; }
12+
string Description { get; set; }
13+
}
14+
15+
public class DumbData : IDumbData
16+
{
17+
public int Id { get; set; }
18+
public string Name { get; set; }
19+
public string Description { get; set; }
20+
}
21+
22+
public abstract class BaseDecrator : IDumbData
23+
{
24+
protected IDumbData data;
25+
26+
public BaseDecrator(IDumbData data) => this.data = data;
27+
28+
public virtual int Id { get => data.Id; set => data.Id = value; }
29+
public virtual string Name { get => data.Name; set => data.Name = value; }
30+
public virtual string Description { get => data.Description; set => data.Description = value; }
31+
}
32+
33+
public class InjectedFunctionality : BaseDecrator
34+
{
35+
// supply original known object as parameter
36+
// enables composability
37+
public InjectedFunctionality(IDumbData data) : base(data) { }
38+
39+
public override string Name
40+
{
41+
get => data.Name;
42+
set
43+
{
44+
data.Name = value
45+
EmitEvent(value);
46+
}
47+
}
48+
49+
private void EmitEvent(string name)
50+
{
51+
// added functionality/responsiblity is not know to the outside,
52+
// in favour of ability to pick decoration at runtime
53+
}
54+
}

decorator/funcational.linq

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<Query Kind="Program" />
2+
3+
void Main()
4+
{
5+
Func<int, int, int> add = PrintResult(Add);
6+
Func<int, int, int> addPrintSquare = Square(add);
7+
Func<int, int, int> addSquarePrint = PrintResult(Square(Add));
8+
9+
add(5, 5);
10+
addPrintSquare(5, 5).Dump("after");
11+
addSquarePrint(5, 5);
12+
}
13+
14+
public int Add(int a, int b) => a + b;
15+
16+
public Func<int, int, int> PrintResult(Func<int, int, int> fn)
17+
{
18+
return (int a, int b) =>
19+
{
20+
int result = fn(a, b);
21+
22+
result.Dump("inside");
23+
24+
return result;
25+
};
26+
}
27+
28+
public Func<int, int, int> Square(Func<int, int, int> fn)
29+
{
30+
return (int a, int b) =>
31+
{
32+
int result = fn(a, b);
33+
return result * result;
34+
};
35+
}

decorator/simpler.linq

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<Query Kind="Program" />
2+
3+
void Main()
4+
{
5+
var d = new Doer();
6+
d.Something();
7+
"---".Dump();
8+
9+
var atd = new AnotherThing(d);
10+
atd.Something();
11+
"---".Dump();
12+
13+
var iad = new InAddition(d);
14+
iad.Something();
15+
"---".Dump();
16+
17+
var iaatd = new InAddition(atd);
18+
iaatd.Something();
19+
"---".Dump();
20+
21+
var atiad = new AnotherThing(iad);
22+
atiad.Something();
23+
}
24+
25+
public interface IDoSomething
26+
{
27+
void Something();
28+
}
29+
30+
public class Doer : IDoSomething
31+
{
32+
public void Something() => "Something".Dump();
33+
}
34+
35+
public class AnotherThing : IDoSomething
36+
{
37+
protected IDoSomething _doSomething;
38+
39+
public AnotherThing(IDoSomething doSomething) => _doSomething = doSomething;
40+
41+
public void Something()
42+
{
43+
_doSomething.Something();
44+
"Another Thing".Dump();
45+
}
46+
}
47+
48+
public class InAddition : IDoSomething
49+
{
50+
protected IDoSomething _doSomething;
51+
52+
public InAddition(IDoSomething doSomething) => _doSomething = doSomething;
53+
54+
public void Something()
55+
{
56+
_doSomething.Something();
57+
"In Addition".Dump();
58+
}
59+
}

proxy/protection.linq

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<Query Kind="Program" />
2+
3+
void Main()
4+
{
5+
6+
}
7+
8+
public interface ISettings
9+
{
10+
string GetConfig();
11+
}
12+
13+
public class Settings : ISettings
14+
{
15+
string _config;
16+
17+
public Settings(string config) => _config = config;
18+
19+
public string GetConfig() => _config;
20+
}
21+
22+
public class ProtectedSettings : ISettings
23+
{
24+
AuthService _auth;
25+
Settings _config;
26+
27+
public ProtectedSettings(AuthService auth)
28+
{
29+
_auth = auth;
30+
_config = new Settings("config");
31+
}
32+
33+
public string GetConfig()
34+
{
35+
if (!_auth.Allowed)
36+
{
37+
throw new Exception("not allowed");
38+
}
39+
return _config.GetConfig();
40+
}
41+
}
42+
43+
public class AuthService
44+
{
45+
public bool Allowed => false;
46+
}

proxy/remote.linq

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<Query Kind="Program" />
2+
3+
void Main()
4+
{
5+
6+
}
7+
8+
public interface ISettings
9+
{
10+
string GetConfig();
11+
}
12+
13+
public class Settings : ISettings
14+
{
15+
string _config;
16+
17+
public Settings(string config) => _config = config;
18+
19+
public string GetConfig() => _config;
20+
}
21+
22+
public class RemoteSettings : ISettings
23+
{
24+
Settings _config;
25+
26+
public RemoteSettings(string address)
27+
{
28+
// fetch from appsettings/db/registry etc...
29+
_config = new Settings("config");
30+
}
31+
32+
public string GetConfig() {
33+
34+
return "";
35+
}
36+
}

proxy/the_fine_line.linq

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<Query Kind="Program" />
2+
3+
void Main()
4+
{
5+
6+
}
7+
8+
public interface Abstraction { }
9+
10+
public class Concretion : Abstraction { }
11+
12+
public class ConcretionProxy : Abstraction
13+
{
14+
// hide concretion, if we inject it we already exposed it
15+
// compile time decision
16+
Concretion concretion = new Concretion();
17+
18+
// simulate/hook/intercept/interupt communication with Concretion
19+
}
20+
21+
public class CocretionDecorator : Abstraction
22+
{
23+
Abstraction _abstraction;
24+
25+
// concretion is known
26+
// runtime decsion
27+
public CocretionDecorator(Abstraction abstraction)
28+
{
29+
_abstraction = abstraction;
30+
}
31+
32+
// override concretion functionality
33+
}

proxy/virtual.linq

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<Query Kind="Program" />
2+
3+
void Main()
4+
{
5+
var a = new Lazy<string>(() => "Hello World".Dump("a"));
6+
var b = a.Value;
7+
var c = a.Value;
8+
}
9+
10+
public interface ISettings
11+
{
12+
string GetConfig();
13+
}
14+
15+
public class Settings : ISettings
16+
{
17+
string _config;
18+
19+
public Settings(string config) => _config = config;
20+
21+
public string GetConfig() => _config;
22+
}
23+
24+
public class LazyRemoteSettings : ISettings
25+
{
26+
Settings _config;
27+
28+
public LazyRemoteSettings(string address)
29+
{
30+
// prepare some http/db
31+
}
32+
33+
public string GetConfig()
34+
{
35+
if (_config == null)
36+
{
37+
// fetch from appsettings/db/registry etc...
38+
_config = new Settings("config");
39+
}
40+
return "";
41+
}
42+
}

0 commit comments

Comments
 (0)