Suppose I have an object that observes an IObservable so that it's always aware of the current state of some external source. Internally my object has a method that uses that external value as part of the operation:
public class MyObject
{
public MyObject(IObservable<T> externalSource) { ... }
public void DoSomething()
{
DoSomethingWith(CurrentT);
}
}
What's the idomatic 'reactive' way of using IObservable for 'tracking current state' instead of 'responding to stream of events'.
Idea #1 is to just monitor the observable and write down values as they come in.
public class MyObject
{
private T CurrentT;
public MyObject(IObservable<T> externalSource)
{
externalSource.Subscribe((t) => { CurrentT = t; });
}
public void DoSomething()
{
DoSomethingWith(CurrentT);
}
}
And that's fine, but keeping track of the state in a class member seems very un-reactive-y.
Idea #2 is to use a BehaviorSubject
public class MyObject
{
private readonly BehaviorSubject<T> bs;
public MyObject(BehvaiorSubject<T> externalSource)
{
this.bs = externalSource
}
public void DoSomething()
{
DoSomethingWith(bs.Value);
}
}
But using subjects directly seems to be frowned upon. But at least in this case I have the ability to use a readonly field to store the behaviorsubject.
The BehaviorSubject (or ReplaySubject) does seem like it was made for this purpose, but is there some other better way here? And if I should use the subject, would it make more sense to take the subject as an injected parameter, or take the original observable and build the subject locally in the constructor?
(by the way I'm aware about the need to deal with the 1st value if the source observable hasn't fired yet. Don't get hung up on that, that's not what I'm asking about)
I'd go with a generic solution utilizing the ReactiveUI library. RUI has a standard way of mapping IObservable<T> to an INotifyPropertyChanged stateful property.
public class ObservableToINPCObject<T> : ReactiveObject, IDisposable
{
ObservableAsPropertyHelper<T> _ValueHelper;
public T Value {
get { return _ValueHelper.Value; }
}
public ObservableToINPCObject(IObservable<T> source, T initial = default(T))
{
_ValueHelper = source.ToProperty(this, p=>p.Value, initial);
}
public Dispose(){
_ValueHelper.Dispose();
}
}
ValueHelper is contains both the current state of the observable and automatically triggers the correct INPC notification when the state changes. That's quite a bit of boiler plate handled for you.
and an extension method
public static class ObservableToINPCObject {
public static ObservableToINPCObject<T> ToINPC<T>
( this IObservable<T> source, T init = default(T) )
{
return new ObservableToINPCObject(source, init);
}
}
now given an
IObservable<int> observable;
you can do
var obj = observable.ToINPC(10);
and to get the latest value
Console.WriteLine(obj.Value);
also given that Value is an INPC supporting property you can use it in databinding. I use ToProperty all the time for exposing my observables as properties for WPF databinding.
To be Rx-ish I'd suggest avoiding the second option and go with your first, but modified in one of two ways.
Either (1) make your class disposable so that you can cleanly close off the subscription to the observables or (2) make a method that lets you clean up individual observables.
(1)
public class MyObject : IDisposable
{
private T CurrentT;
private IDisposable Subscription;
public MyObject(IObservable<T> externalSource)
{
Subscription = externalSource
.Subscribe((t) => { CurrentT = t; });
}
public void Dispose()
{
Subscription.Dispose();
}
public void DoSomething()
{
DoSomethingWith(CurrentT);
}
}
(2)
public class MyObject
{
private T CurrentT;
public IDisposable Observe(IObservable<T> externalSource)
{
return externalSource
.Subscribe((t) => { CurrentT = t; });
}
public void DoSomething()
{
DoSomethingWith(CurrentT);
}
}
Both allow proper clean-up and both don't use a subject.
Related
What is the proper usage of Activation/Deactivation in conjunction with ObservableAsPropertyHelper? Given a view and viewmodel that reflects long lived (hot) observables, the subscription would need to be disposed when the view and viewmodel is unloaded. However ObservableAsPropertyHelper, which is recommended to be readonly is assigned in the constructor of the viewmodel, and cannot be part of the activation/deactivation lifecycle. What is the right way to handle these kind of situations?
public interface ILongLivedObject
{
IObservable<bool> Status { get; }
}
public class TestViewModel : ReactiveObject
{
private readonly ObservableAsPropertyHelper<bool> _status;
public bool Status => _status.Value;
public TestViewModel(ILongLivedObject obj)
{
_status = obj.Status.ToProperty(this, vm => vm.Status); //how is the subscription disposed?
}
}
This also gets me into a corner when trying to add commands that depends on this status. In my application, a common use case is to have some hardware that is on some specific status (e.g. IsOpen) and allow commands when it is true.
Without knowing better, this is what I am trying to do:
public class TestViewModel : ReactiveObject
{
private readonly ObservableAsPropertyHelper<bool> _status;
public bool Status => _status.Value;
public ReactiveCommand<Unit, Unit> DoStuff {get;}
public TestViewModel(ILongLivedObject obj)
{
_status = obj.Status.ToProperty(this, vm => vm.Status); //how is the subscription disposed?
DoStuff = ReactiveCommand.CreateFromTask(....., this.WhenAnyValue(this, x => x.Status);
}
}
If I try to move the _status creation into this.WhenActivated, the app will crash as the command is trying to get the value of status before it is created. Am I supposed to (re)create the comand during activation? This seems wrong and pretty costly?
So far, it seems better to have a regular Status property with a protected setter and make a regular subscription in this.WhenActivated - but this is what the handbook tells to avoid for "readonly" properties.
So one thing to be aware of in Reactive programming, disposing often means "unsubscribe".
You often don't need to unsubscribe since the garbage collector will take care of it for you, providing you create ObservableAsPropertyHelper (abbreviated as OAPH) only with observables generated from the current ViewModel.
In your case however, your observable/object, is related to a object outside the current ViewModel. The OAPH itself is a Disposable object.
So you can use ISupportsActivation (shortly going to have a replacement of IActivableViewModel) and pass your OAPH into it's Disposable property.
public class TestViewModel : ReactiveObject, ISupportsActivation
{
private readonly ObservableAsPropertyHelper<bool> _status;
public bool Status => _status.Value;
public ViewModelActivator Activator { get; } = new ViewModelActivator();
public TestViewModel(ILongLivedObject obj)
{
_status = obj.Status.ToProperty(this, vm => vm.Status);
this.WhenActivated(disposables =>
{
disposables(_status);
}
}
}
The disposables parameter passed into the WhenActivated lambda is a Func that takes a IDisposable
In the view, make sure you derive off IActivatable (soon to be renamed IActivatableView) and use WhenActivated in the constructor of the view as well.
I've implemented the command pattern (in a multi-support way) in my application.
Structure:
class MultiCommand : BaseCommand
abstract class BaseCommand : ICommand
Process Flow:
var commandsGroup = new MultiCommand(new List<ICommand>()
{
new Command1(),
new Command2(),
new Command3(),
});
commandsGroup.Execute()
Now, suppose that in Command1 a somethingID is changed and I'll use this new value in Command2... And also, that there are plenty of other properties and objects that are being affected during the whole execution process.
Also, there are some interface implementations that should be available at any command just using the context object like:
Context.ServerController.something();
The instantiation of the IServerController will take place just before the multiCommandGroup initialization.
How can I have a shared context like this for all Commands of the group?
Example of the Context class:
public class CommandContext
{
public IServerController ServerController;
public RequiredData Data { get; set; }
public CommandContext(){}
}
IMPORTANT
A minimal implementation Code is here
1) If you want to keep this interface, then you have to pass this context as constructor parameter:
new MultiCommand(new List<ICommand>()
{
new Command1(context),
new Command2(context),
new Command3(context),
})
2) As another option you can accept list of delegates instead of list of commands.
MultiCommand will be look like this:
class MultiCommand : ICommand
{
public MultiCommand(List<Func<Context, Command>> commands, Context context)
}
That is almost the same except MultiCommand is responsible for all the commands share the same context.
3) Looks like commands in MultiCommand depends on result of previous command. In this case Command pattern is not probably the best. Maybe you should try to implement Middleware chain here?
interface IMiddleware<TContext>
{
void Run(TContext context);
}
class Chain<TContext>
{
private List<IMiddleware<TContext>> handlers;
void Register(IMiddleware<TContext> m);
public void Run(TContext context)
{
handlers.ForEach(h => h.Run(context));
}
}
I would suggest to make somethings generic. Here is a super simple example.
class MultiCommand<TContext>
{
List<Command<TContext>> Commands;
TContext Context;
}
You could have a constructor on your BaseCommand class (and its derived classes) that would accept a Context class of some kind. When instantiating the commands that will belong to the same group, you could provide them all the same context object. Maybe something like:
public class CommandContext
{
// The object that will be the target of the commands' actions.
public object Data { get; set; }
// ... any other properties that might be useful as shared state between commands...
}
public abstract class BaseCommand : ICommand
{
protected CommandContext Context { get; private set; }
public BaseCommand(CommandContext ctx)
{
Context = ctx;
}
}
public class ChangeSomethingIDCommand : BaseCommand
{
public ChangeSomethingIDCommand(CommandContext ctx) : base(ctx)
{ }
public void Execute()
{
var target = (SomeDomainClass)Context.Data;
target.SomethingID++;
}
}
// Elsewhere in your code (assuming 'myTargetDomainClassInstance' is
// a SomeDomainClass instance that has been instantiated elsewhere and
// represents the object upon which the commands will do work):
var ctx = new CommandContext { Data = myTargetDomainClassInstance };
var commandGroup = new MultiItemCommand(ctx, new List<ICommand>
{
new ChangeSomethingIDCommand(ctx),
new Command2(ctx),
new Command3(ctx)
});
commandGroup.Execute();
Consider a Functional Style
public class SomeMainClass{
public void MultiCommandInit()
{
MultiCommand.New()
.Add(new Command1())
.Add(new Command2())
.Add(new Command3())
.SharedContext(CC => {
CC.Data = new RequiredData();
CC.ServerController = GetServerController();
});
}
private IServerController GetServerController()
{
// return proper instance of server controller
throw new NotImplementedException();
}
}
Requires this extension method / function...
public static class XMultiCommand
{
// How can I have a shared context like this for all Commands of the group?
public static MultiCommand SharedContext(this MultiCommand mc, Action<CommandContext> CallBack)
{
var cc = new CommandContext();
CallBack(cc);
mc.SharedContext = cc;
return mc;
}
}
Finally, these changes to MultiCommand
public class MultiCommand
{
private System.Collections.Generic.List<ICommand> list;
public List<ICommand> Commands { get { return list; } }
public CommandContext SharedContext { get; set; }
public MultiCommand() { }
public MultiCommand(System.Collections.Generic.List<ICommand> list)
{
this.list = list;
}
public MultiCommand Add(ICommand cc)
{
list.Add(cc);
return this;
}
internal void Execute()
{
throw new NotImplementedException();
}
public static MultiCommand New()
{
return new MultiCommand();
}
}
Cool Things Happen Using Functional Styles
Re-usability soars!
Hyper focus on Single Responsibility concerns
Composition becomes the Norm
Code Maintenance becomes simple
Intellisense becomes your built-in API (just use code commenting)
No radical OOP design patterns are needed
Fluent code becomes very enjoyable to work with
Nested / Decorated Functions are much more easy to imagine and implement
You will never repeat youerself
The Open/Closed principal becomes your religion
Code is now always Clear, Complete and Concise
Some even say no interfaces are needed any longer
In your case, going with injecting context through constructor is fine as mentioned by others. But in general, I would go with injecting the context through method parameters instead:
public class Command1: BaseCommand
{
//inject as parameter instead
public void Execute(Context ctx)
{
}
}
The reasons are:
The context should be managed by CommandGroup so that we have better encapsulation.
The CommandGroup is responsible for executing its list of commands so that it's possible for the CommandGroup to pass to each Command only the parameters each Command really needs, these parameters may be constructed at runtime (maybe by previous Commands) so that it's not possible to pass in these objects as the time we construct the list of commands. Therefore, it's easier to reuse Command and also simplify unit testing these Commands as we don't need to construct the whole context object in unit tests.
Maybe you don't need to care about these things at the moment, but method injection gives more flexibility. If you have worked with some frameworks in .NET, you would see something similar like OwinContext, FilterContext,.. they are passed as parameters and contain relevant information for that context.
In my opinion, your case is not a good fit for Command pattern. A Command represents a user request (action) and these objects could be created dynamically at runtime, but you're predefining your Commands at coding time.
What you're trying to do looks like owin middleware or asp.net web api message handler which are http://www.dofactory.com/net/chain-of-responsibility-design-pattern
And what about changing your approach? I did an architecture for DDD recently and executing a commad implies atomic operation (retrieve aggregate root from persitence, apply domain rules and pesist the aggregate) so I do not in needed of a share context and can batch multiple commands whithout worries.
Here you have an cqrs architecture that use command pattern with the above strategy I posted.
My 0.02:
1) The MultiCommand class looks like a Composite pattern.
You may want to add a GetParentCommand() method at the base command class and add an AddChildCommand() method at the MultiCommand class, which set every children's parent.
Then the children commands could get the context object from its parent. (Context object should also be defined in base class. And it may be of generic type.)
edit:
abstract class BaseCommand<T> : ICommand
{
public T Context { get; set; }
public BaseCommand Parent { get; set; }
}
class MultiCommand : BaseCommand
{
public void AddChildCommand(BaseCommand command)
{
command.parent = this; // we can get parent's context from children now
// put the command in an internal list
}
}
var commandsGroup = new MultiCommand();
commandsGroup.AddChildCommand(new Command1());
commandsGroup.AddChildCommand(new Command2());
commandsGroup.AddChildCommand(new Command3());
commandsGroup.Execute()
2) We may create a global singleton context object. In MultiCommand's Execute function, we could set the current context object before executing children's Execute function. Then child command could just access the singleton context object. And after all children's execution, the MultiCommand could reset the context. (The context is actually a stack here.)
edit:
abstract class BaseCommand : ICommand
{
// it could be put anywhere else as long as it can be accessed in command's Execute
// it can also be a stack
public static CommandContext Context {get; set;}
}
class MutliCommand : BaseCommand
{
public void Execute()
{
// do something to BaseCommand.Context
ChildCommand.Execute();
// do something to BaseCommand.Context
}
}
class ChildComand: BaseCommand
{
void Execute()
{
// do something with BaseCommand.Context
}
}
Another option is to put the context object as a parameter of the Execute function:
class MultiCommand : BaseCommand
{
void Execute(CommandContext context)
{
Children.Execute(context);
}
}
How,does one should call an event declared by interface so that all the classes that has implemented that interface get notified??
For example in structure like this,
public delegate void myDel(int value);
interface IEventCaller{
event myDel myDelEventCall;
}
public Class One : IEventCaller {
public event myDel myDelEventCall;
}
public Class Two : IEventCaller {
public event myDel myDelEventCall;
}
I want both class One and Two to get notify and act as event gets called, I am feeling somewhere I am going wrong direction , is it possible to do?
Actually what you want doesn't involve events. Events would be used by an object implementing IEventCaller to notify some object holding a reference to that object of some change. To invoke something on the object implementing IEventCaller would just require a method, for example Hello();
First, you need code that informs all the objects that implement this interface. To make that possible, you somewhere need to store a list of instances that want to get notified.
One solution would be to create a class that manages that list. Let's say like this
private static List<IEventCaller> eventCallers = new List<IEventCaller>();
public static void AddEventCaller(IEventCaller c)
{
eventCallers.Add(c);
}
public static void RemoveEventCaller(IEventCaller c)
{
eventCallers.Remove(c);
}
public static IEventCaller[] EventCallers
{
get { return eventCallers.ToArray() }
}
Of course this code needs to be thread safe, etc. I'd put all this into a singleton to be globally available.
Then, all objects that implement IEventCallers need to register/unregister accordingly. Thus, I'd also have them Implement IDisposable so that in the constructor you can do
public EventCallable()
{
Singleton.Instance.AddEventCaller(this);
}
and in the Dispose method you can do this:
public void Dispose(bool disposing)
{
Singleton.Instance.RemoveEventCaller(this);
}
Now the code that should notify every instance could just do this:
public void NotifyAll()
{
foreach (IEventCaller caller in Singleton.Instance.EventCallers)
caller.Hello();
}
I think you might be looking at this the other one around.
With events, you want to have an object which is the publisher, which is responsible for publishing the event and saying "hey guys, something just occurred and you should know about it", and you have your subscribers, which are the guys who say "Yo dawg, let me know when that thing occurs, so i can act on it".
What you can do is have the object which is responsible for the event occurring implement your interface:
public class Publisher : IEventCaller
{
public event MyDel MyDeleteEvent;
public void OnDeleteOccured()
{
var myDeleteEvent = MyDeleteEvent;
if (myDeleteEvent != null)
{
MyDeleteEvent(1);
}
}
}
And then have your One and Two objects register to that event occurring, where they pass a method which signature matches the delegate type of MyDel:
public class SubscriberOne
{
public void OnSomethingOccured(int value)
{
Console.WriteLine(value);
}
}
public class SubscriberTwo
{
public void OnSomethingOccured(int value)
{
Console.WriteLine(value);
}
}
And the registration goes:
void Main()
{
var publisher = new Publisher();
var subscriberOne = new SubscriberOne();
var subscriberTwo = new SubscriberTwo();
publisher.MyDeleteEvent += subscriberOne.OnSomethingOccured;
publisher.MyDeleteEvent += subscriberTwo.OnSomethingOccured;
}
I have some classes that caches data from a database, these classes are loaded with data when their static constructor gets called.
I need to call a static Reload method at all these classes, except those that is not initialized yet.
E.g.: City caches data from a database
public class City
{
public City Get(string key)
{
City city;
FCities.TryGetValue(key, out city);
return city;
}
private static Dictionary<string, City> FCities;
static City()
{
LoadAllCitiesFromDatabase();
}
public static void Reload()
{
LoadAllCitiesFromDatabase();
}
private static void LoadAllCitiesFromDatabase()
{
// Reading all citynames from database (a very slow operation)
Dictionary<string, City> loadedCities = new Dictionary<string, City>();
...
FCities = loadedCities;
}
}
The problem is that City might not have been used yet (it might not be used in this service) and there is no reason to load it from the database then.
My reload all method looks much like this:
public static class ReloadAll
{
public static void Do()
{
foreach (Type classType in AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => a.GetTypes()).Where(t => t.IsClass && !t.IsAbstract))
{
MethodInfo staticReload = classType.GetMethods().FirstOrDefault(m => m.IsStatic && m.IsPublic && m.ReturnType == typeof(void) && m.Name == "Reload" && m.GetParameters().Length == 0);
if (staticReload != null)
{
if (StaticConstructorHasBeenCalled(classType))
staticReload.Invoke(null, null);
}
}
}
private bool StaticConstructorHasBeenCalled(Type classType)
{
// How do I check if static constructor has been called?
return true;
}
}
I need a little help with implementing StaticConstructorHasBeenCalled.
At first glance, I thought this could be an issue where <grin> Quantum Mechanical Copenhagen interpretation might apply ("As soon as you look at it, it changes"). </grin> I.e. anything you do in the class to observe whether it has been initialized would probably cause it to initialize itself...
But you don't have to do it in the class, just keep a list somewhere else (other than in any of these static classes) that is populated by every static class when it gets initialized. Then in your reset function, just iterate through the classes in the list.
If you have several of these classes, how about controlling their instantiation through a factory or manager class.
This could keep track of which have been used and call the reload methods where appropriate.
You should not use long-running operations in the static constructor, or at least, they should not run synchronously. Static constructor run implicitly, and when implicit execution takes significant time, it makes for interesting bugs :)
Also, if you do use static constructors, methods and whatnot that maintain state, try to isolate them in a fully static class, so they will, for most scenarios, act like singletons. I would change the implementation to something along these lines:
public static class CityRepository
{
private static bool areCitiesLoaded;
private List<City> cities;
static CityRepository()
{
areCitiesLoaded = false;
cities = new List<City>();
}
//method that will be called in all other method, to ensure
//that the cities are loaded
private static void EnsureLoad()
{
if (!areCitiesLoaded)
{
LoadAllCitiesFromDatabase();
areCitiesLoaded = true;
}
}
}
public class City {} //city instance methods
you could use the singleton pattern, and add a field that will tell you if the unique instance has already been created
actually no need to make a singleton, just keep your static class, and load the data when the property getter that should return it is called:
static class City
{
static bool _loaded = false;
public bool Loaded { get { return _loaded; } }
public static List<C> Data
{
get
{
if (!_loaded)
{
doLoading();
_loaded = true
}
}
}
}
I asked if there was any way to see if a static constructor was called. I think that the answer was no, but a workaround would be to create a manager that could keep track of repositories.
The goal was to change as little as possible to the existing classes.
My solution to a manager class is:
public static class RepositoryManager
{
public delegate void Reload();
private static List<Reload> FRepositories = new List<Reload>();
public static void Register(Reload repository)
{
lock (FRepositories)
{
FRepositories.Add(repository);
}
repository();
}
public static void ReloadAll()
{
List<Reload> list;
lock (FRepositories)
{
list = new List<Reload>(FRepositories);
}
foreach (Reload repository in list)
repository();
}
}
Using the example with the City class the changes would be limited to the static constructor.
public class City
{
// ...
static City()
{
RepositoryManager.Register(LoadAllCitiesFromDatabase);
}
// ...
}
My ReloadAll method would then be as simple as:
public void ReloadAll()
{
RepositoryManager.ReloadAll();
}
Thank you for all your answers, I have rewarded each of you that suggested some kind of a manager as a solution to the problem.
The drawback of this solution is that whenever someone creates a repository that needs to be reloaded/updated/cleared once in a while they have to remember to use the RepositoryManager.
I have a method which should return a snapshot of the current state, and another method which restores that state.
public class MachineModel
{
public Snapshot CurrentSnapshot { get; }
public void RestoreSnapshot (Snapshot saved) { /* etc */ };
}
The state Snapshot class should be completely opaque to the caller--no visible methods or properties--but its properties have to be visible within the MachineModel class. I could obviously do this by downcasting, i.e. have CurrentSnapshot return an object, and have RestoreSnapshot accept an object argument which it casts back to a Snapshot.
But forced casting like that makes me feel dirty. What's the best alternate design that allows me to be both type-safe and opaque?
Update with solution:
I wound up doing a combination of the accepted answer and the suggestion about interfaces. The Snapshot class was made a public abstract class, with a private implementation inside MachineModel:
public class MachineModel
{
public abstract class Snapshot
{
protected internal Snapshot() {}
abstract internal void Restore(MachineModel model);
}
private class SnapshotImpl : Snapshot
{
/* etc */
}
public void Restore(Snapshot state)
{
state.Restore(this);
}
}
Because the constructor and methods of Snapshot are internal, callers from outside the assembly see it as a completely opaque and cannot inherit from it. Callers within the assembly could call Snapshot.Restore rather than MachineModel.Restore, but that's not a big problem. Furthermore, in practice you could never implement Snapshot.Restore without access to MachineModel's private members, which should dissuade people from trying to do so.
Can MachineModel and Snapshot be in the same assembly, and callers in a different assembly? If so, Snapshot could be a public class but with entirely internal members.
I could obviously do this by
downcasting, i.e. have CurrentSnapshot
return an object, and have
RestoreSnapshot accept an object
argument which it casts back to a
Snapshot.
The problem is that somebody could then pass an instance of an object which is not Snapshot.
If you introduce an interface ISnapshot which exposes no methods, and only one implementation exists, you can almost ensure type-safety at the price of a downcast.
I say almost, because you can not completely prevent somebody from creating another implementation of ISnapshot and pass it, which would break. But I feel like that should provide the desired level of information hiding.
You could reverse the dependency and make Snapshot a child (nested class) of MachineModel. Then Snapshot only has a public (or internal) Restore() method which takes as a parameter an instance of MachineModel. Because Snapshot is defined as a child of MachineModel, it can see MachineModel's private fields.
To restore the state, you have two options in the example below. You can call Snapshot.RestoreState(MachineModel) or MachineModel.Restore(Snapshot)*.
public class MachineModel
{
public class Snapshot
{
int _mmPrivateField;
public Snapshot(MachineModel mm)
{
// get mm's state
_mmPrivateField = mm._privateField;
}
public void RestoreState(MachineModel mm)
{
// restore mm's state
mm._privateField = _mmPrivateField;
}
}
int _privateField;
public Snapshot CurrentSnapshot
{
get { return new Snapshot(this); }
}
public void RestoreState(Snapshot ss)
{
ss.Restore(this);
}
}
Example:
MachineModel mm1 = new MachineModel();
MachineModel.Snapshot ss = mm1.CurrentSnapshot;
MachineModel mm2 = new MachineModel();
mm2.RestoreState(ss);
* It would be neater to have Snapshot.RestoreState() as internal and put all callers outside the assembly, so the only way to do a restore is via MachineModel.RestoreState(). But you mentioned on Jon's answer that there will be callers inside the same assembly, so there isn't much point.
This is an old question, but i was looking for something very similar and I ended up here and between the information reported here and some other I came up with this solution, maybe is a little overkill, but this way the state object is fully opaque, even at the assembly level
class Program
{
static void Main(string[] args)
{
DoSomething l_Class = new DoSomething();
Console.WriteLine("Seed: {0}", l_Class.Seed);
Console.WriteLine("Saving State");
DoSomething.SomeState l_State = l_Class.Save_State();
l_Class.Regen_Seed();
Console.WriteLine("Regenerated Seed: {0}", l_Class.Seed);
Console.WriteLine("Restoring State");
l_Class.Restore_State(l_State);
Console.WriteLine("Restored Seed: {0}", l_Class.Seed);
Console.ReadKey();
}
}
class DoSomething
{
static Func<DoSomething, SomeState> g_SomeState_Ctor;
static DoSomething()
{
Type type = typeof(SomeState);
System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(type.TypeHandle);
}
Random c_Rand = new Random();
public DoSomething()
{
Seed = c_Rand.Next();
}
public SomeState Save_State()
{
return g_SomeState_Ctor(this);
}
public void Restore_State(SomeState f_State)
{
((ISomeState)f_State).Restore_State(this);
}
public void Regen_Seed()
{
Seed = c_Rand.Next();
}
public int Seed { get; private set; }
public class SomeState : ISomeState
{
static SomeState()
{
g_SomeState_Ctor = (DoSomething f_Source) => { return new SomeState(f_Source); };
}
private SomeState(DoSomething f_Source) { Seed = f_Source.Seed; }
void ISomeState.Restore_State(DoSomething f_Source)
{
f_Source.Seed = Seed;
}
int Seed { get; set; }
}
private interface ISomeState
{
void Restore_State(DoSomething f_Source);
}
}