EventAggregator
๊ฐ์
EventAggregator๋ ์ด๋ฒคํธ์ ๊ตฌ๋ (Subscribe)๊ณผ ์ถํ(Publish)์ ๋งค์ปค๋์ฆ์ ๊ฐ์ง๊ณ ์๋ ๊ตฌ์กฐ์์.์ด ํจํด์ ์ฌ์ฉํ๋ฉด ์ด๋ฒคํธ๋ค์ ๊ด๋ฆฌํ๋ ๊ธฐ๋ฅ์ ์ ๊ณตํ์ฌ ์๋๋ฐฉ์ ์ง์ ์ ์ธ ์ฐธ์กฐ ์์ด ์ด๋ฒคํธ๋ฅผ ์ฒ๋ฆฌํ ์ ์๋๋ก ๋์์ค ์ ์์๊บผ์์.
๊ตฌ์กฐ ์์๋ณด๊ธฐ
public interface IEventAggregator;
public interface IApplicationEvent;
public class EventAggregator : IEventAggregator;
๋จผ์ ๋ง์ด ์ฌ์ฉํ๋ ๊ตฌ์กฐ๋ฅผ ์์๋ณด๊ธฐ๋ก ํด์. ์ด ํจํด์ ์ด๋ฃจ๋ ์ธ ๊ฐ์ ํด๋์ค์ ์ธํฐํ์ด์ค๋ก ์ด๋ฃจ์ด์ ธ์์ด์. ์์ธํ ์ฌ์ฉ๋ฒ์ ์กฐ๊ธ ํ์ ์์๋ณด๊ธฐ๋ก ํ๊ณ ํ๋์ฉ ์ค๋ช ํด ๋ณผ๊ป์.
public interface IEventAggregator
{
void Subscribe<T>(Action<T> action) where T : IApplicationEvent;
void Unsubscribe<T>(Action<T> action) where T : IApplicationEvent;
void Publish<T>(T message) where T : IApplicationEvent;
}
IEventAggregator ์ธํฐํ์ด์ค๋
์ด๋ฒคํธ๋ฅผ ๋ฑ๋กํ๋ Subscribe
๋ฑ๋กํ ์ด๋ฒคํธ๋ฅผ ํด์ง ํ๋ Unsubscribe
๋ฑ๋ก๋ ์ด๋ฒคํธ๋ค์๊ฒ ๋ฉ์ธ์ง๋ฅผ ์ ๋ฌํ๋ Publish ๋ฉ์๋๋ก ์ด๋ฃจ์ด์ ธ์์ด์.
public interface IApplicationEvent
{
}
IApplicationEvent ์ธํฐํ์ด์ค๋ ์ค์ ๋ก ์๋ฌด ์ฝ๋๋ ์กด์ฌํ์ง ์๋๋ฐ, ์ IEventAggregator ์ where ์ ์ฝ ์กฐ๊ฑด์ ๊ฑธ๊ธฐ ์ํด ์ฌ์ฉํ์ด์.
ํ์ ์ ์ฝ์ EventAggregator๋ฅผ ์ฌ์ฉํ๋ ์ด๋ฒคํธ์ ์๋ ์ด๋ฒคํธ๋ฅผ ๋๋๋๋ฐ ์ ์ฉํด์.
public class EventAggregator : IEventAggregator
{
private readonly ConcurrentDictionary<Type, List<object>> subscriptions =
new ConcurrentDictionary<Type, List<object>>();
public static IEventAggregator Instance { get; } = new EventAggregator();
public void Publish<T>(T message) where T : IApplicationEvent
{
List<object> subscribers;
if (subscriptions.TryGetValue(typeof(T), out subscribers))
{
// To Array creates a copy in case someone unsubscribes in their own handler
foreach (var subscriber in subscribers.ToArray())
{
((Action<T>) subscriber)(message);
}
}
}
public void Subscribe<T>(Action<T> action) where T : IApplicationEvent
{
var subscribers = subscriptions.GetOrAdd(typeof(T), t => new List<object>());
lock (subscribers)
{
subscribers.Add(action);
}
}
public void Unsubscribe<T>(Action<T> action) where T : IApplicationEvent
{
List<object> subscribers;
if (subscriptions.TryGetValue(typeof(T), out subscribers))
{
lock (subscribers)
{
subscribers.Remove(action);
}
}
}
public void Dispose()
{
subscriptions.Clear();
}
}
์ค์ ํด๋์ค๋ ์์ ๊ฐ์ด ๋ฉํฐ ์ค๋ ๋์ ์์ ํ๋๋ก ๊ตฌํํ์ด์. ConcurrentDictionary๋ ํ์์ ๋ฐ๋ผ ์ด๋ฒคํธ๋ค์ ๊ด๋ฆฌํ๋ List ๊ฐ์ฒด๋ฅผ ๊ฐ์ง๊ณ ์์ด์. ๊ทธ๋ฆฌ๊ณ Aggregator ํด๋์ค๋ ์ฑ๊ธํด ์ธ์คํด์ค๋ก ํ์ฉํ์ด์. ์ด๋ฅผ ํตํด ์ด๋์๋ ํธ์ถ ํ ์ ์๋๋ก ํ์ด์. ๋ง์ง๋ง ํด๋์ค์ ์ฌ์ฉ ํด์ ์์ Dispose๋ฅผ ํตํด Dictionary๋ฅผ ์ด๊ธฐํ ํ์ด์.
์ด๋ฒคํธ ๊ตฌ๋
์ด๋ฒคํธ์ ๊ตฌ๋ ์ ๋จผ์ ๋์์ด ๋๋ ์ด๋ฒคํธ์ ํด๋์ค๋ฅผ ์ ์ํด์ผํด์. ์ ๋ ์ฌ๊ธฐ์์ ์์๋ก ์ด๋ฒคํธ ํด๋์ค์ ๊ทธ ์ด๋ฒคํธ์ arguments๋ฅผ ๋ค๋ฃจ๋ ํด๋์ค๋ฅผ ํ๋ ๋ง๋ค์ด ๋ณผ๊ป์.
public class ProcessCompleteEvent : IApplicationEvent
{
private ProcessCompleteEventArgs args;
public ProcessCompletedEvent(ProcessCompleteEventArgs args)
{
this.args = args;
}
}
public class ProcessCompleteEventArgs
{
public int result = default(int);
public string message = default(string);
public ProcessCompleteEventArgs(int result, string message)
{
this.result = result;
this.message = message;
}
}
๋์์ด ๋ ํด๋์ค์ ์ด๋ฒคํธ๋ฅผ ๋ง๋ค์๋ค๋ฉด, ์ด์ ๊ตฌ๋ ์ ํ ์ฐจ๋ก์์. ๊ตฌ๋ ์ ๋ค์๊ณผ ๊ฐ์ ๊ตฌ์กฐ๋ก ์ด๋ฃจ์ด์ ธ ์์ด์.
๋จผ์ ์ด๋ฒคํธ์ ํธ์ถ ๋์ ๋ฉ์๋๋ฅผ ๋ง๋ค๊ณ , ๊ทธ ๋ฉ์๋๋ฅผ Subscribe ํ๋ ์ฝ๋๋ฅผ ์์ฑํด์.
private void OnEventMethod(ProcessCompleteEvent e)
{
Console.WriteLine(MethodBase.GetCurrentMethod().Name.ToString());
}
EventAggregator.Instance.Subscribe<ProcessCompleteEvent>(OnEventMethod);
์ด๋ฒคํธ ์ ๋ฌํ๊ธฐ
์ด๋ ๊ฒ ์ด๋ฒคํธ๋ฅผ ์ํ ํด๋์ค๋ฅผ ๋ง๋๋ ์์ ์ด ๋๋๋ฉด ์๋์ ๊ฐ์ ์ฝ๋๋ก ์ด๋ฒคํธ๋ฅผ publish ํฉ๋๋ค.
var args = new ProcessCompleteEvent(0, "Test Event Call");
EventAggregator.Instance.Publish<ProcessCompleteEvent>(args);
Last updated