I am working on a C# project and I need to manage a local cache of data and present it on a GUI.
For example I have:
public class DataFromOtherLibrary
Now I want make a class to help translate the information I need out of it
public class MyDataModel
{
private DataFromOtherLibrary cache;
public MyDataModel ( DataFromOtherLibrary Source)
{
cache = Source;
}
public long Field1 { get { return cache.SomeField; } }
public long Field2 { get { return cache.OtherFiled; } }
}
Now the issue I have is I need to create a MyDataModel for every DataFromOtherLibrary it would be nice to have a single translator class. I'm not sure how to do it and still implement properties (which I need to data-bind to).
Thanks
Matt
You should use a Provider with all your DataModels in it Like:
public class MyDataModelProvider
{
public List<MyDataModel> DataModelList { get; set; }
MyDataModelProvider()
{
loadDataModelList();
}
private void LoadDataModel()
{
foreach (Cachobject c in Cache)
{
this.DataModelList.Add(new MyDataModel(c.valueA,c.valueB));
}
}
}
and for this Provider you also need a Factory Like:
[Singleton(true)]
public class DataModelListProviderFactory
{
private static DataModelListProvider dataListProvider;
public DataModelListProvider getInstance()
{
if (dataListProvider == null)
{
dataListProvider = new DataModelListProvider();
return dataListProvider;
}
else
return dataListProvider;
}
}
Because now you have a single Spot with all your DataModels and you only must recieve them once. You can also easily search the List for a specific Model if you have a case or you show all the Data in a View.
You can read here more about Factory Patterns.
Hope that helps.
Related
I've made a class with T. It looks like this.
public interface ISendLogic<T> where T : NarcoticsResult
{
ChangeType Change_New();
ChangeType Change_Cancel();
PurchaseType Purchase_New();
PurchaseType Purchase_Cancel();
}
public class SendLogic<T> : ISendLogic<T> where T : NarcoticsResult
{
private eReportType _type;
private bool Send_Change()
{
// Send to server by xml file
}
private bool Send_Purchase()
{
// Send to server by xml file
}
public ChangeType Change_New()
{
_type = change_new;
Send_Change();
}
public ChangeType Change_Cancel()
{
_type = change_cancel;
Send_Change();
}
public PurchaseType Purchase_New()
{
_type = purchase_new;
Send_Purchase();
}
public PurchaseType Purchase_Cancel()
{
_type = purchase_cancel;
Send_Purchase();
}
}
There are two types, ChangeType and PurchaseType
and these are inherited from NarcoticsResult.
I thought the person who want to use this class would use it like this.
// this class can only be used when someone wants to use change function
var logic = SendLogic<ChangeType >();
logic.Change_New();
logic.Change_Cancel();
Here is a question.
I want to force this class to be used only as I thought.
I mean, I want to prevent it to be used like this.
var logic = SendLogic<ChangeType>();
logic.Change_New(); // OK
logic.Purchase_New(); // You should make this class like SendLogic<PurchaseType>()
I thought I add some code which check type of T in every function.
How do you think the way I thought. I think there are better way to fix it
Please tell me a better way
thank you.
Personally, I don't think you need a generic class in this case. What you need is either an abstract base class or an interface. I personally love the interface approach as below:
public interface ISendLogic {
void New();
void Cancel();
}
So now you've got a contract that will force the consumer of your code to use New or Cancel methods only.
The next step you can implement that send logic interface for your specific implementation:
public class ChangeSendLogic : ISendLogic {
private eReportType _type;
public ChangeSendLogic(
/*you can put the necessary parameters in the constructor
and keep it as private fields in the object*/
)
{
}
private bool Send_Change()
{
// Send to server by xml file
}
public void New()
{
_type = change_new;
Send_Change();
}
public void Cancel()
{
_type = change_cancel;
Send_Change();
}
}
public class PurchaseSendLogic : ISendLogic {
private eReportType _type;
public PurchaseSendLogic(
/*you can put the necessary parameters in the constructor
and keep it as private fields in the object*/
)
{
}
private bool Send_Purchase()
{
// Send to server by xml file
}
public void New()
{
_type = change_new;
Send_Purchase();
}
public void Cancel()
{
_type = change_cancel;
Send_Purchase();
}
}
From here you can see those two classes handle the implementation for each type nicely. You can think this is as an implementation of single responsibility principle. So if you have one more type, you can just add one more implementation of this interface rather than updating the existing classes.
If you want to hide the creation of those objects, in the next part you can introduce a kind of factory or selector as below:
public enum SendLogicType {
Change,
Purchase
}
public static SendLogicSelector {
public static ISendLogic GetSendLogic(SendLogicType type)
{
switch(type)
{
case SendLogicType.Change:
return new ChangeSendLogic();
case SendLogicType.Purchase:
return new PurchaseSendLogic();
}
}
}
This is how the code will be consumed:
ISendLogic sendLogic = SendLogicSelector.GetSendLogic(SendLogicType.Change);
sendLogic.New(); // change new logic executed
sendLogic.Cancel(); // change cancel logic executed
sendLogic = SendLogicSelector.GetSendLogic(SendLogicType.Purchase);
sendLogic.New(); // purchase new logic executed
sendLogic.Cancel(); // purchase cancel logic executed
Hopefully, you can get the idea of my approach. Good luck! :)
Thank you for your comment
I divided it into two parts like below
public class ChangeSendLogic : SendLogic<ChangeType>, IChangeLogic
public class PurchaseSendLogic : SendLogic<PurchaseType>, IPurchaseLogic
And I also divided interface too
public interface IChangeLogic
{
ChangeType Change_New();
ChangeType Change_Cancel();
}
public interface IPurchaseLogic
{
PurchaseType Purchase_New();
PurchaseType Purchase_Cancel();
}
And I made SendLogic<T> class to abstract class.
This is because I want to make the person who wants to use this class to use a class that inherits from this class without directly accessing it.
Thank you for your comment. I got a good idea.
I'd like to have two simple calls in a class that would be transformed by other classes. Something like:
ObjectCreator.CreateBlank<Human>();
ObjectCreator.CreatePopulated<Human>();
ObjectCreator.CreateBlank<Dog>();
ObjectCreator.CreatePopulated<Dog>();
I currently do this:
public class ObjectCreator
{
public static T CreateBlank<T>()
{
return Activator.CreateInstance<T>();
}
public static T CreatePopulated<T>()
{
//Somehow return new object with populated properties
}
}
I am struggling with the populated part. I'd like it to return a "default" object of that type with defined properties. I've tried a few things involving passing in interfaces, but it gets messy fast (I don't expect this to be particularly clean either)
So If I called ObjectCreator.CreatePopulated(), I'd like it to somehow go to a different class where I create a new Anything, and fill it's properties to specific values. It feels like I'm close but missing a piece of the puzzle here.
My end game here is to have the call be as simple / readable as possible.
Any help is appreciated.
I DO realize it'd probably be easier to simply call a class that creates and populates each object, but this is a learning exercise for me and I'd like to attempt to get this working as generically as possible.
I would recommend doing something like this:
public interface IPopulatable
{
void Populate();
}
public class ObjectCreator
{
public static T CreateBlank<T>() where T : new ()
{
return new T();
}
public static T CreatePopulated<T>() where T : IPopulatable, new()
{
var populatable = new T();
populatable.Populate();
return populatable;
}
}
public class Human : IPopulatable
{
public string Name { get; set; }
public void Populate()
{
Name = "Joe";
}
}
I currently have a WPF project that makes use of MVVM. In my project, I make use of a static class which acts as a cache for collections used by the various controls in my app, something like this:
public static class AppCache
{
public static ObservableCollection<MyObject> MyObjects { get; set; }
private static async void GetMyObjectsAsync()
{
await Task.Run(() => GetMyObjects());
Mediator.Instance.NotifyColleagues("MyObjectsUpdatedMessage", true); // A helper class that implements messaging
}
private static GetMyObjects()
{
// Get objects via service call
...
MyObjects = result;
}
static AppCache()
{
MyObjects = new ObservableCollection<MyObject>();
GetMyObjectsAsync();
}
}
I then subscribe to the mediator in my various viewmodels:
public class MyViewModel : ViewModelBase
{
...
public ObservableCollection<MyObject> MyObjects
{
// My ViewModelBase lets me implement INotifyPropertyChanged like this
get { return GetValue(() => MyObjects); }
set { SetValue(() => MyObjects, value); }
}
[Message("MyObjectsUpdatedMessage")]
private void OnMyObjectSourceUpdated(bool c)
{
MyObjects = AppCache.MyObjects;
}
public MyViewModel ()
{
Mediator.Instance.RegisterHandler<bool>("MyObjectsUpdatedMessage", OnMyObjectSourceUpdated);
}
}
The problem I have with this method is that when I do things with the collections in the ViewModels (eg. add or edit a MyObject) I then have to go back and manually update the global AppCache collection and make sure it matches up with what is in the ViewModel, then make sure that I update all of the other ViewModels using this collection to use the new value since there is no binding involved: MyOtherViewModel.MyObjects = AppCache.MyObjects
The alternative is to make GetMyObjectsAsync() public and have the AppCache update itself from the database after I make changes from my ViewModel, then use the Mediator to update all the other views using the collection. I don't like this either as it means I end up making a service call I don't want to.
What I'm trying to figure out is if there is any way to use Reactive Extensions to simplify my process, such that I can have some kind of Reactive Property defined in the AppCache which my ViewModels subscribe to, and which when updated will push its updates out to all the ViewModels, something of a mix between the two options available to me (Manually update the AppShared collection but then have all its subs notified without needing the mediator).
I suppose really what I want is to have a property that is essentially bindable and shareable between ViewModels.
Is there any kind of Reactive Property I can use to achieve this sort of thing? Something like:
EDIT:
I was able to get the subscription to work as follows, but this is again similar to the option of using the Mediator as I have to call NotifyMyObjectChanged whenever I update MyObjects. Is there a way to make MyObjectsObservable 'listen' for changes to MyObjects and automatically call NotifyMyObjectChanged? If there isn't a way to do this, is there a benefit to using RX for this over the Mediator?
public static class AppCache
{
public static ObservableCollection<MyObject> MyObjects { get; set; }
public static IObservable<ObservableCollection<MyObject>> MyObjectsObservable => _mySubject; // C# 6 syntax
public static Subject<ObservableCollection<MyObject>> _mySubject { get; set; }
private static async void GetMyObjectsAsync()
{
await Task.Run(() => GetMyObjects());
NotifyMyObjectChanged() // this basically just replaces the mediator
}
private static GetMyObjects()
{
...
MyObjects = result;
}
private static void NotifyMyObjectChanged()
{
_mySubject.OnNext(MyObjects);
}
static AppCache()
{
_mySubject = new Subject<ObservableCollection<MyObject>>();
GetMyObjectsAsync();
}
}
public class MyViewModel : ViewModelBase
{
ObservableCollection<MyObject> MyObjects
{
get { return GetValue(() => MyObjects); }
set { SetValue(() => MyObjects, value); }
}
IDisposable _subscription { get; }
MyViewModel()
{
_subscription = AppCache.MyObjectsObservable.Subscribe (HandleMyObjectChanged);
}
private void HandleMyObjectChanged(ObservableCollection<MyObject> myObjects)
{
MyObjects = myObjects;
}
public void Dispose()
{
_subscription.Dispose();
}
}
So what you want to do is something like this:
public static class AppCache
{
static AppCache()
{
_mySubject = new Subject<MyObject>();
}
private static void NotifyMyObjectChanged(MyObject object)
{
_mySubject.OnNext(object);
}
public static IObservable<MyObject> MyObjectsObservable
{
get { return _mySubject; }
}
}
public class MyViewModel : ViewModelBase
{
MyViewModel()
{
_subscription = AppCache.MyObjectsObservable.
.Where(x => x == value)
.Subscribe (HandleMyObjectChanged);
}
private void HandleMyObjectChanged(MyObject object)
{
... do work here ....
}
public void Dispose()
{
_subscription.Dispose();
}
}
In this case what you're basically doing here is sending a notification to your view model that something on your MyObject has changed. You can take the object variable from the handler and use that to copy the changed properties into your view model. Alternatively you could send a "message" class that has a list of properties and their new values, that might be a little lighter than sending the entire object.
The other thing to keep in mind is that the Observable might send the "event" on a thread other than the UI thread. There's a Subscribe override that lets you specific a TaskScheduler to use, so you can specify the UI scheduler so you don't have to do the marshalling yourself.
As I said in my comment, there are tons of ways to do this, so you'll have to play around to find something that fits your needs the best, but hopefully this gives you some direction.
UPDATE
So here's a bit of an update to your AppCache code (from your edit), but your question is basically that you want to get rid of the mediator and replace it with RX. In the end, you still end up with a mediator of some sort, you just have to decide whether RX gives you something more than your own implementation of a mediate would. I would (and do) use RX, but it's really a preference thing, so you're going to have to do some research on your own.
This shows you the use of the Observable.FromEventPattern function, which is pretty useful and gives you a nice shortcut:
public static class AppCache
{
ObservableCollection<MyObject> MyObjects { get; set; }
public static IObservable<ObservableCollection<MyObject>> MyObjectsObservable { get; private set; }
private static async void GetMyObjectsAsync()
{
await Task.Run(() => GetMyObjects());
NotifyMyObjectChanged() // this basically just replaces the mediator
}
private static GetMyObjects()
{
...
MyObjects = result;
MyObjectsObservable = Observable.FromEventPattern(h=>MyObjects.CollectionChanged += h, h=>MyObjects.CollectionChanged -= h);
}
static AppCache()
{
GetMyObjectsAsync();
}
}
I wanted to show you the usuage but this code isn't perfect, if a subscriber calls Subscribe before the MyObjectsObservable is created, obviously it would blow up.
Here's another link that shows you a lot of the stuff that RX can do, that to me makes it a great tool: http://www.introtorx.com/uat/content/v1.0.10621.0/04_CreatingObservableSequences.html#
I have a container class called PaymentPlan, which holds basic Payment summary info. It also holds a list of ExpectedPayments. Hopefully a fairly basic OOP type question, my brain appears to have gone to sleep - I have a property in the ExpectedPayment class which needs to interrogate a property on the PaymentPlan class to determine the result.
I'm currently storing a reference to the PaymentPlan as a property on the ExpectedPayment class, however, it has a public getter, and following DDD, I feel this is a bit of a code smell. Is there a better way to achieve what I want?
I've removed all but the necessary bits as an example:
public class PaymentPlan
{
private readonly List<ExpectedPayment> _payments;
public PaymentPlan(List<ExpectedPayment> payments)
{
... Other Stuff
//TODO: Fix this smell
_payments = payments;
_payments.ForEach(p => p.Plan = this);
}
... Other Properties
}
And the ExpectedPayment class:
public class ExpectedPayment
{
public ExpectedPayment(... Args removed for example)
{
}
//TODO: Attempting to avoid this public setter as I have no control..
public PaymentPlan Plan { get; set; }
public PaymentState PaymentState
{
get
{
if (Plan.SomePropertyOnPlan == "SomeValue")
{
return PaymentState.SomeState;
}
else
{
... Other logic to determine the payment state of this expected payment.
}
}
}
... Other Properties
}
Any help appreciated! - I would like to know some techniques if possible as know there are multiple ways to achieve what I'm after.
Thanks,
Alex
As if ExpectedPayment shouldn't exist if it hasn't any PaymentPlan, you must force your ExpectedPayment() constructor to provide PaymentPlan to caller and add a "friendly" method for adding new ExpectedPlan on PaymentPlan .
public class ExpectedPayment
{
public ExpectedPayment(PaymentPlan plan, ..... other args)
{
Plan = plan ;
plan.AddExpectedPlan(this) ;
......
}
......
....
public class PaymentPlan
{
.........
internal void AddExpectedPlan(ExpectedPlan expectedPlan)
{
...........
_payments.Add(expectedPlan) ;
}
}
I've encountred a confusing problem while developping a user library in c# in which i've created two classes that implement an interface that is called by the API as a separated plugin...
(that means that after the compilation the API detect 2 plugins although they are from same project)
What i'm trying to do is to enable communication between those two plugins. Accuratly i want to transfer an object (it's reference not a copy) from a plugin to another... but i'm failing!
I tried to make one of those plugins Singleton and reach it from the other, but since the API require a public constructor, I was forced to imitate the singleton work, and effectively i've reached the instance of the plugin, but i'm enable to reach its properties...
Let me schematize that through simplified code:
let's say this is class A (the one that imitate the singleton)
Class A:IPlugin
{
private static volatile A _instance;
public static A Instance
{
get { return _instance; }
}
public A()
{
if (_instance == null) _instance = this; // as i'm sure it's called once
}
public Foo F{get;set} // THIS IS INITIALIZED SOMEWHERE IN THAT PLUGIN'S CONTEXT
}
and this is the class that tries to extract objects from A
Class B:IPlugin
{
FindFoo()
{
Foo Fb = A.Instance.F; // THAT IS ALWAYS NULL
}
}
A very important indication and the one that may create the problem is that:
A.F is bound to a WPF control...
I hope I've clearly transmitted my issue and you'll be able to help me because i'm stuck !
Try the following ;
public interface IPlugin {
string Foo { get; set;}
}
public class A : IPlugin {
private static A _inslance { get; set;}
public static A Instance {
get {
if (_inslance == null){
_inslance = new A();
}
return _inslance;
}
}
public string Foo { get; set;}
}
public class B : IPlugin {
public string GetMeFooOfA {
get {
return A.Instance.Foo;
}
}
public string Foo { get; set;}
}
void Main()
{
A.Instance.Foo = "Test 123";
var b = new B();
Console.WriteLine(b.GetMeFooOfA);
}
You may want to look at a DI (Dependency Injection), such as Unity, Ninject, etc.. framework which would offer you a good platform to work on when you develop modular code