using singleton and mediator in order to communicate between projects
I have project calles Warehouse. In the warehouse there are Products. I want to write the option to inform the warehouse about expected products. This is how I am thinking of doing that:
- Create a new Warehose.Common project which will be referenced by other projects that willing to interact the warehouse.
- In the Warehose.Common project I will create an interface to Product and call it IProduct.
Use singleton and mediator design patterns as follows (not sure I implement those design patterns properly):
public sealed class ExpectedProductsMediator { private static volatile ExpectedProductsMediator _Instance; private static object _SyncRoot = new Object(); delegate IEnumerable<INoteProduct> ExpectedProductsGenerator(DateTime startDate, DateTime endDate); private IList<ExpectedProductsGenerator> _ExpectedProductsGenerators; private ExpectedProductsMediator() { _ExpectedProductsGenerators = new List<ExpectedProductsGenerator>(); } public static ExpectedProductsMediator Instance {开发者_高级运维 get { if (_Instance == null) { lock (_SyncRoot) { if (_Instance == null) _Instance = new ExpectedProductsMediator(); } } return _Instance; } } public void AddExpectedProductsGenerator(ExpectedProductsGenerator generator) { _ExpectedProductsGenerators.Add(generator); } public void RemoveExpectedProductsGenerator(ExpectedProductsGenerator generator) { _ExpectedProductsGenerators.Remove(generator); } public IEnumerable<INoteProduct> GetExpectedProducts(DateTime startDate, DateTime endDate) { IEnumerable<INoteProduct> products = null; if (_ExpectedProductsGenerators.Any()) { products = _ExpectedProductsGenerators.First()(startDate, endDate); foreach (ExpectedProductsGenerator generator in _ExpectedProductsGenerators.Skip(1)) { products = products.Concat(generator(startDate, endDate)); } } return products; } }
This mediator will be on the Warehouse.Common projects. Now, if project B that would like to provide expected products, it need to register its generator using AddExpectedProductsGenerator() method:
public static class ExpectedProductsRegistrar {
static ExpectedProductsRegistrar() {
ExpectedProductsMediator.Instance.AddExpectedProductsGenerator(someGenerator);
}
}
Whenever the warehouse will need to get the expected products all it has to do is calling GetExpectedProducts() method.
I have two problems with this implementation:
- it expose the GetExpectedProducts() method to all other projects. - In order to register the mediator, I need to use static constractor.What do you think about my implementation? Is there any better solution for such need? Am I using design patterns properly?
I would have your API accept new products and then write to storage (file, DB etc.). Then the Warehouse project reads the expected products from storage. You can then get rid of your singleton and expose as little as possible through the API.
Eventually I used this implementation. I didn't find something better ant this code is easier enough to maitain.
精彩评论