Registering component in autofac - autofac

I'm new to autofac(using 2.1.14.854),and im still trying to put my head around in trying to understand
I have an interface and there are one or more implementations to this interface, and the implementation(s) should be fired in a specific sequence.
For example:
public IPipeline
{
void execute();
}
public MyPipeLine_1:IPipeline
{
public void execute(){}
}
public MyPipeLine_2:IPipeline
{
public void execute(){}
}
foreach(IPipeline pipeline in pipelines)
pipeline.execute();
The order execution of IPipeline should be MyPipleLine_2,MyPipleLine_1, etc
I have two questions
1) how to register all the components, that implements IPipeLine interface in a assembly and place them in a List
2) can i define the order of the execution of these components whilst registering
Thanks in advance.

[A quick note: You're using a really old version of Autofac. You may need to update to get the features I'm talking about.]
The first part is easy - Autofac implicitly supports IEnumerable<T>. Just register all the types and resolve:
var builder = new ContainerBuilder();
builder.RegisterType<MyPipeLine_1>().As<IPipeline>();
builder.RegisterType<MyPipeLine_2>().As<IPipeline>();
var container = builder.Build();
var containsAllPipelineComponents = container.Resolve<IEnumerable<IPipeline>>();
It'd be better if you can take it as an IEnumerable<T> rather than a list, but if you have to have a list, you could add a registration for it:
builder
.Register(c => new List<IPipeline>(c.Resolve<IEnumerable<IPipeline>>()))
.As<IList<IPipeline>>();
The second part isn't as easy. Autofac doesn't necessarily guarantee the order of the items in the list. If you need to order them, you'll need to put some sort of ordering metadata on them - attributes, properties, something that you can use to order the pipeline after the fact.
Alternatively, if your pipeline has "stages" or "events" where different components are applicable, look at the design of your pipeline and have a different pipeline interface per event. Within the event it shouldn't matter what order each item executes in. (This is similar to how event handlers in .NET work now. You'd want to mimic that behavior - different events for different stages in the overall lifecycle, but within each specific stage the order of execution of handlers doesn't matter.)
An example might look like:
public interface IFirstStage
{
void Execute();
}
public interface ISecondStage
{
void Execute();
}
public interface IThirdStage
{
void Execute();
}
public class PipelineExecutor
{
public IEnumerable<IFirstStage> FirstHandlers { get; private set; }
public IEnumerable<ISecondStage> SecondHandlers { get; private set; }
public IEnumerable<IThirdStage> ThirdHandlers { get; private set; }
public PipelineExecutor(
IEnumerable<IFirstStage> first,
IEnumerable<ISecondStage> second,
IEnumerable<IThirdStage> third)
{
this.FirstHandlers = first;
this.SecondHandlers = second;
this.ThirdHandlers = third;
}
public void ExecutePipeline()
{
this.ExecuteFirst();
this.ExecuteSecond();
this.ExecuteThird();
}
public void ExecuteFirst()
{
foreach(var handler in this.FirstHandlers)
{
handler.Execute();
}
}
// ExecuteSecond and ExecuteThird look just
// like ExecuteFirst, but with the appropriate
// set of handlers.
}
Then when you register your handlers it's simple:
var builder = new ContainerBuilder();
builder.RegisterType<SomeHandler>().As<IFirstStage>();
builder.RegisterType<OtherHandler>().As<IFirstStage>();
builder.RegisterType<AnotherHandler>().As<ISecondStage>();
// You can have any number of handlers for any stage in the pipeline.
// When you're done, make sure you register the executor, too:
builder.RegisterType<PipelineExecutor>();
And when you need to run the pipeline, resolve and run.
var executor = container.Resolve<PipelineExecutor>();
executor.ExecutePipeline();
This is just like event handlers but not using delegates. You have a fixed order of pipeline "events" or "stages" but the handlers inside each stage aren't guaranteed order.
If you need to modify the pipeline to have more stages, yes, you'll need to modify code. Just like if you had a new event you wanted to expose. However, to add, remove, or change handlers, you just modify your Autofac registrations.

I suggest you to use Metadata feature.
It gives you an advantage to define the order on registration stage.
Here is an example:
internal class Program
{
private static void Main(string[] args)
{
var builder = new ContainerBuilder();
var s1 = "First";
var s2 = "Second";
var s3 = "Third";
builder.RegisterInstance(s1).As<string>().WithMetadata<Order>(c => c.For(order => order.OrderNumber, 1));
builder.RegisterInstance(s2).As<string>().WithMetadata<Order>(c => c.For(order => order.OrderNumber, 2));
builder.RegisterInstance(s3).As<string>().WithMetadata<Order>(c => c.For(order => order.OrderNumber, 3));
using (var container = builder.Build())
{
var strings = container.Resolve<IEnumerable<Meta<string, Order>>>();
foreach (var s in strings.OrderBy(meta => meta.Metadata.OrderNumber))
{
Console.WriteLine(s.Value);
}
}
Console.ReadKey();
}
public class Order
{
public int OrderNumber { get; set; }
}
}

Related

How to implement a State Pattern for Blazor pages using multiple components to build a page?

I have a Blazor page that utilizes multiple components within it - how can I implement a State pattern (ideally per-page) that would be able to handle the current state of a page?
Currently I have all of the state and state-manipulation being done on the page (and via injected Services), but I imagine it would be cleaner to implement a state pattern where each page has some kind of State object which then allows you to manipulate the page and its components in a strict manner.
Ideally the State object would implement INotifyPropertyChanged and be able to dynamically have its State updated, but I also don't hate the idea of having the State object relegate State-manipulation to methods on the object to make sure state isn't just 1-off updated on the Blazor page.
I've already tried to implement some kind of MVVM pattern, but that turned into more questions than answers.
I started to create a State object for the current page being worked on, but I'm not sure if I should basically just be putting most of the logic that was on the Blazor page in the State object, or if I should still have some data, but delegating the heavy lifting to the State.
eg: I have some code that used to be in the "OnAfterRenderAsync" function on the Blazor page, but I'm in the process of moving basically everything in there to a "LoadMatterDetails()" function in the State object that is handling that. Does this make sense, or should I only really have object State in the state object, and writing to & reading from the State object when particular pieces of information are available?
public class MatterDetailsState : IMatterDetailsState
{
private readonly IMatterDetailsService matterDetailsService;
private readonly NavigationManager navigationManager;
public bool EditMode { get; private set; } = false;
public int EditMatterId { get; private set; } = 0;
public Matter Matter { get; set; } = new();
public MatterPaymentOptionDetails PaymentDetails { get; set; } = new();
public List<MatterStatus> MatterStatuses { get; private set; } = new();
public MatterDetailsState(
IAppState appState,
IMatterDetailsService matterDetailsService,
NavigationManager navigationManager)
{
this.matterDetailsService = matterDetailsService;
this.navigationManager = navigationManager;
}
public async Task LoadMatterDetails()
{
// Query Params handling
var uri = navigationManager.ToAbsoluteUri(navigationManager.Uri);
var decryptedUri = HelperFunctions.Decrypt(uri.Query);
var queryParamFound = QueryHelpers.ParseQuery(decryptedUri).TryGetValue("MatterID", out StringValues uriMatterID);
if (queryParamFound)
{
EditMatterId = Convert.ToInt32(uriMatterID);
EditMode = !String.IsNullOrEmpty(uriMatterID) && EditMatterId > 0;
}
await LoadMatterStatuses();
if (EditMode)
{
Matter = await matterDetailsService.GetMatterByIdAsync(EditMatterId);
PaymentDetails = await matterDetailsService.GetMatterPaymentInfoByMatterId(EditMatterId);
}
}
private async Task LoadMatterStatuses()
{
MatterStatuses = await matterDetailsService.GetAvailableMatterStatusesAsync();
}
}
Basically, should I instead of having more or less the entire function in the State object, or only make the calls like setting Matter & PaymentDetails go through functions in the State object? Not sure what the standard for this is.
I've used Fluxor, which is a Flux/Redux library for Blazor, and have liked it. It holds all your state in an object which you can inject into your component for read access. You then manage state by dispatching actions from your components which are processed by effects or reducers which are essentially methods that process the action and make changes to state. It keeps everything neat, separated and very testable in my experience.
https://github.com/mrpmorris/Fluxor
There isn't a "standard", but applying good coding practices such as the "Single Responsivity Principle" and Clean Design principles drives you in a certain direction.
I divide the presentation and UI code into three:
UI - components and UI logic
State - data that you want to track state on.
Data Management - getting, saving,....
Each represented by one or more objects (Data Management is the ViewModel in MVVM).
You can see an example of this in this answer - https://stackoverflow.com/a/75157903/13065781
The problem is then how do you create a ViewModel instance that is scoped the same as the Form component. You either:
Scope the VM as transient - you can cascade it in the form if sub components need direct access to it. This is the approach in the referenced example.
Create an instance from the IServiceProvider using ActivatorUtilities and deal with the disposal in the form component.
If the VM implements IDisposable/IAsycDisposable the you have to do the second.
The following extension class adds two methods to the IServiceProvider that wrap up this functionality.
public static class ServiceUtilities
{
public static bool TryGetComponentService<TService>(this IServiceProvider serviceProvider,[NotNullWhen(true)] out TService? service) where TService : class
{
service = serviceProvider.GetComponentService<TService>();
return service != null;
}
public static TService? GetComponentService<TService>(this IServiceProvider serviceProvider) where TService : class
{
var serviceType = serviceProvider.GetService<TService>()?.GetType();
if (serviceType is null)
return ActivatorUtilities.CreateInstance<TService>(serviceProvider);
return ActivatorUtilities.CreateInstance(serviceProvider, serviceType) as TService;
}
}
Your form then can look something like this:
public partial class UIForm: UIWrapperBase, IAsyncDisposable
{
[Inject] protected IServiceProvider ServiceProvider { get; set; } = default!;
public MyEditorPresenter Presenter { get; set; } = default!;
private IDisposable? _disposable;
public override Task SetParametersAsync(ParameterView parameters)
{
// overries the base as we need to make sure we set up the Presenter Service before any rendering takes place
parameters.SetParameterProperties(this);
if (!initialized)
{
// Gets an instance of the Presenter from the Service Provider
this.Presenter = ServiceProvider.GetComponentService<MyEditorPresenter>() ?? default!;
if (this.Presenter is null)
throw new NullReferenceException($"No Presenter could be created.");
_disposable = this.Presenter as IDisposable;
}
return base.SetParametersAsync(ParameterView.Empty);
}
//....
public async ValueTask DisposeAsync()
{
_disposable?.Dispose();
if (this.Presenter is IAsyncDisposable asyncDisposable)
await asyncDisposable.DisposeAsync();
}
}

How can I use IWantToRunBeforeConfigurationIsFinalized , inject propertys into the handlers *and* continue using the Nservicebus test framework?

Nervicebus 4.6 Unit Testing issue
I recently discovered IWantToRunBeforeConfigurationIsFinalized to inject propertys into a handler, changed all my service code and now suddenly all my NserviceBus.Test fails.
public void run {
Configure.Instance.Configurer.ConfigureProperty<MyMessage_Handler>(h => h.MyProperty, "somevalue");
}
When i atttempt a unit test
var message = new MyMessage
{
...
...
};
Test.Handler<MyMessage_Handler>().WithExternalDependencies(m =>
{
m.PropertyA = aValue;
m.PropertyB = bValue;
})
.ExpectPublish<MyEvent>(m =>
{
Assert.That(...);
return true;
})
.OnMessage<MyMessage>(message);
I receive the following exception
TestFixture failed: SetUp : System.InvalidOperationException : Cannot
configure properties for a type that hasn't been configured yet:
at
NServiceBus.ObjectBuilder.Autofac.AutofacObjectBuilder.ConfigureProperty(Type
component, String property, Object value) in
y:\BuildAgent\work\31f8c64a6e8a2d7c\src\NServiceBus.Core\ObjectBuilder\Autofac\AutofacObjectBuilder.cs:line
114
However if i configure the bus like this, calling configurecomponent on the handler. The test framework works
This was my original method, it works fine but i prefer the approach of IWantToRunBeforeConfigurationIsFinalized to cleanly seperate the logic.
Configure.With()
.DefaultBuilder()
.PurgeOnStartup(false)
.RunCustomAction(() => Configure.Instance.Configurer.ConfigureComponent<MyMessage_Handler>(DependencyLifecycle.InstancePerUnitOfWork))
.RunCustomAction(() => {
Configure.Instance.Configurer.ConfigureProperty<MyMessage_Handler>(h => h.MyProperty, "myValue");
}
...
How can I use IWantToRunBeforeConfigurationIsFinalized , inject propertys into the handlers and continue using the Nservicebus test framework?
It seems odd to try to configure properties directly on handlers. If it's only needed by one handler, then it should be dealt with in that handler, perhaps in a static constructor in that handler class.
At any rate, you're putting yourself at the mercy of when types are loaded up and registered into the container, which isn't necessarily deterministic across different versions of NServiceBus, and clearly not when dealing with the testing framework.
Instead, what if you created a new class:
public class ReferenceValues
{
public string MyProperty { get; set; }
}
Then, you could register this type normally, from any point in the endpoint startup. Preferably, as an INeedInitialization since most of the extensibility points go away in NServiceBus 5.x and INeedInitialization is really the only game in town.
// V4 code
public class SetupReferenceValues : INeedInitialization
{
public void Init()
{
Configure.Component<ReferenceValues>(DependencyLifecycle.SingleInstance)
.ConfigureProperty(rv => rv.MyProperty, "myValue");
}
}
Then, in your handler:
public class MyHandler : IHandleMessages<MyMessage>
{
public ReferenceValues Values { get; set; }
public void Handle(MyMessage message)
{
Console.WriteLine(Values.MyProperty);
}
}
I believe this should work from the testing framework as well.

Restoring data 1 minute ago for time-shifted sequence

This class accumulates values + knows at current moment the difference between current sum and sum 1 minute ago. Its client uses it in such way: adds new value for every incoming data chunk and gets the difference. Now, there's a problem with restoring its state. Suppose application gets recycled, and this data in pump for previous minute is lost and first minute after recycling Change will equal 0, so I'd have to wait for a minute to be able to calculate difference. How to fix it?
public class ChangeEstimator
{
private int sum;
private Subject<int> sumPump;
private IConnectableObservable<int> hotSumPump;
public int Sum
{
get
{
return sum;
}
private set
{
sum = value;
sumPump.OnNext(value);
}
}
public int Change { get; private set; }
public void Start()
{
sumPump = new Subject<int>();
hotSumPump = sumPump.Publish();
var changePeriod = TimeSpan.FromMinutes(1);
hotSumPump.Delay(changePeriod)
.Subscribe(value =>
{
Change = Sum - value;
});
hotSumPump.Connect();
}
public void AddNewValue(int newValue)
{
Sum += newValue;
}
}
UPDATE
In the code below you can see the explanation. The client subscribes to transaction stream, and with every new transaction it updates the estimator. Also client exposes IObservable source of snapshots which pushes snapshot of data to listeners which can be UI or database. The problem is when recycling happens, UI will be shown not real Change but 0. If this problem is too specific for Stackoverflow please forgive me. I was advised to use RabbitMQ to keep persistence of changes. Do you think it could work for this problem?
public class Transaction
{
public int Price { get; set; }
}
public class AlgorithmResult
{
public int Change { get; set; }
}
public interface ITransactionProvider
{
IObservable<Transaction> TransactionStream { get; }
}
public class Client
{
private ChangeEstimator estimator = new ChangeEstimator();
private ITransactionProvider transactionProvider;
public Client(ITransactionProvider transactionProvider)
{
this.transactionProvider = transactionProvider;
}
public void Init()
{
transactionProvider.TransactionStream.Subscribe(t =>
{
estimator.AddNewValue(t.Price);
});
}
public IObservable<AlgorithmResult> CreateSnaphotsTimedSource(int periodSeconds)
{
return Observable
.Interval(TimeSpan.FromSeconds(periodSeconds))
.Select(_ =>
{
AlgorithmResult snapshot;
snapshot = new AlgorithmResult
{
Change = estimator.Change
};
return snapshot;
})
.Where(snapshot => snapshot != null);
}
}
Your application gets restarted and has no memory (pun intended) of its previous life. No Rx tricks (within this application) can help you.
As discussed, you should figure out the business requirements and consider state initialization during startup.
You might want to consider storing latest state via I/O source or separating application logic between message sender and consumer in order to implement a queue.
I have to answer my own question because I got an answer from someone and this works in my case. I agree that the correct answer depends on the business logic and I think I had explained it as clearly as I could.
So, here the right way to deal with possible application recycle is to put the class ChangeEstimator to outer process and exchange messages with it.
I use AMQP to send messages to estimator (RabbitMQ). To key point here is that the risk that external process will close/recycle is really small compared to that of web application in which the rest is contained.

How can I marry AutoCompleteBox.PopulateComplete method with the MVVM paradigm?

Here is the setup:
I have an autocompletebox that is being populated by the viewmodel which gets data from a WCF service. So it's quite straightforward and simple so far.
Now, I am trying to follow the principles of MVVM by which the viewmodel doesn't know anything about the view itself. Which is good, because I bound the Populating event of the autocomplete box to a method of my viewmodel via triggers and commands.
So the view model is working on fetching the data, while the view is waiting. No problems yet.
Now, the view model got the data, and I passed the collection of results to a property bound to the ItemSource property of the control. Nothing happens on the screen.
I go to MSDN and to find the officially approved way on how this situation is supposed to be handled (http://msdn.microsoft.com/en-us/library/system.windows.controls.autocompletebox.populating(v=vs.95).aspx):
Set the MinimumPrefixLength and MinimumPopulateDelay properties to
values larger than the default to minimize calls to the Web service.
Handle the Populating event and set the PopulatingEventArgs.Cancel
property to true.
Do the necessary processing and set the ItemsSource property to the
desired item collection.
Call the PopulateComplete method to signal the AutoCompleteBox to show
the drop-down.
Now I see a big problem with the last step because I don't know how I can call a method on a view from the view model, provided they don't know (and are not supposed to know!) anything about each other.
So how on earth am I supposed to get that PopulateComplete method of view called from the view model without breaking MVVM principles?
If you use Blend's Interactivity library, one option is an attached Behavior<T> for the AutoCompleteBox:
public class AsyncAutoCompleteBehavior : Behavior<AutoCompleteBox>
{
public static readonly DependencyProperty SearchCommandProperty
= DependencyProperty.Register("SearchCommand", typeof(ICommand),
typeof(AsyncAutoCompleteBehavior), new PropertyMetadata(null));
public ICommand SearchCommand
{
get { return (ICommand)this.GetValue(SearchCommandProperty); }
set { this.SetValue(SearchCommandProperty, value); }
}
protected override void OnAttached()
{
this.AssociatedObject.Populating += this.PopulatingHook;
}
protected override void OnDetaching()
{
this.AssociatedObject.Populating -= this.PopulatingHook;
}
private void PopulatingHook(object sender, PopulatingEventArgs e)
{
var command = this.SearchCommand;
var parameter = new SearchCommandParameter(
() => this.AssociatedObject
.Dispatcher
.BeginInvoke(this.AssociatedObject.PopulateComplete),
e.Parameter);
if (command != null && command.CanExecute(parameter))
{
// Cancel the pop-up, execute our command which calls
// parameter.Complete when it finishes
e.Cancel = true;
this.SearchCommand.Execute(parameter);
}
}
}
Using the following parameter class:
public class SearchCommandParameter
{
public Action Complete
{
get;
private set;
}
public string SearchText
{
get;
private set;
}
public SearchCommandParameter(Action complete, string text)
{
this.Complete = complete;
this.SearchText = text;
}
}
At this point you need to do 2 things:
Wire up the Behavior
<sdk:AutoCompleteBox MinimumPopulateDelay="250" MinimumPrefixLength="2" FilterMode="None">
<i:Interaction.Behaviors>
<b:AsyncAutoCompleteBehavior SearchCommand="{Binding Search}" />
</i:Interaction.Behaviors>
</sdk:AutoCompleteBox>
Create a DelegateCommand which handles your aysnc searching.
public class MyViewModel : ViewModelBase
{
public ICommand Search
{
get;
private set;
}
private void InitializeCommands()
{
this.Search = new DelegateCommand<SearchCommandParamater>(DoSearch);
}
private void DoSearch(SearchCommandParameter parameter)
{
var client = new WebClient();
var uri = new Uri(
#"http://www.example.com/?q="
+ HttpUtility.UrlEncode(parameter.SearchText));
client.DownloadStringCompleted += Downloaded;
client.DownloadStringAsync(uri, parameter);
}
private void Downloaded(object sender, DownloadStringCompletedEventArgs e)
{
// Do Something with 'e.Result'
((SearchCommandParameter)e.UserState).Complete();
}
}

How do I find the output model type in a behavior?

With FubuMVC, I'm not sure what the best way is to determine the current action's output model type. I see different objects that I could get the current request's URL from. But that doesn't lead to a very good solution.
What's the easiest way to get the current action's output model type from the behavior?
If this isn't a good practice, what's a better way?
First, I'm assuming you've already got your settings object(s) set up in StructureMap and have the ISettingsProvider stuff already wired up.
The best, simplest thing to do would be just to pull the settings in the view, like this:
<%: Get<YourSettingsObject>().SomeSettingProperty %>
If you insist on having these be a property on your output model, then continue reading:
Let's say you had a settings object like this:
public class OutputModelSettings
{
public string FavoriteAnimalName { get; set; }
public string BestSimpsonsCharacter { get; set; }
}
Then you had an output model like this:
public class OutputModelWithSettings
{
public string SomeOtherProperty { get; set; }
public OutputModelSettings Settings { get; set; }
}
You'll need to do a few things:
Wire up StructureMap so that it will do setter injection for Settings objects (so it will automatically inject the OutputModelSettings into your output model's "Settings" property.
Set up a setter injection policy in your StructureMap initialization code (a Registry, Global ASAX, your Bootstrapper, etc -- wherever you set up your container).
x.SetAllProperties(s => s.Matching(p => p.Name.EndsWith("Settings")));
Create your behavior to call StructureMap's "BuildUp()" on the output model to trigger the setter injection. The behavior will be an open type (i.e. on the end) so that it can support any kind of output model
public class OutputModelSettingBehavior<TOutputModel> : BasicBehavior
where TOutputModel : class
{
private readonly IFubuRequest _request;
private readonly IContainer _container;
public OutputModelSettingBehavior(IFubuRequest request, IContainer container)
: base(PartialBehavior.Executes)
{
_request = request;
_container = container;
}
protected override DoNext performInvoke()
{
BindSettingsProperties();
return DoNext.Continue;
}
public void BindSettingsProperties()
{
var viewModel = _request.Find<TOutputModel>().First();
_container.BuildUp(viewModel);
}
}
Create a convention to wire up the behavior
public class OutputModelSettingBehaviorConfiguration : IConfigurationAction
{
public void Configure(BehaviorGraph graph)
{
graph.Actions()
.Where(x => x.HasOutput &&
x.OutputType().GetProperties()
.Any(p => p.Name.EndsWith("Settings")))
.Each(x => x.AddAfter(new Wrapper(
typeof (OutputModelSettingBehavior<>)
.MakeGenericType(x.OutputType()))));
}
}
Wire the convention into your FubuRegistry after the Routes section:
ApplyConvention<OutputModelSettingBehaviorConfiguration>();
In your view, use the new settings object:
<%: Model.Settings.BestSimpsonsCharacter %>
NOTE: I have committed this as a working sample in the FubuMVC.HelloWorld project in the Fubu source. See this commit: https://github.com/DarthFubuMVC/fubumvc/commit/2e7ea30391eac0053300ec0f6f63136503b16cca