Pass simple parameter to unity Container - wpf

I have a key "MyKey" It can have a value "Key1" or "Key2".
Now i need to pass to container "MyKey" and value "Key1".
Can this be done without creating a Interface object in Container??
Any methods to go about.
public class KeyMode:IKeyMode
{
private string keyMode;
public KeyMode(string keyMode)
{
this.keyMode= keyMode;
}
public string getKeyMode()
{
return keyMode;
}
}
public interface IKeyMode
{
string getKeyMode();
}
KeyMode rcm = new KeyMode("key1");
container.RegisterInstance<IKeyMode>(rcm);
I have created IUnityContainer object "container" and a class KeyMode and a interface...I am creating Keymode object and registering value to container to pass.
Instead of KeyMode object creation. Is there a method to directly pass to container object in key value pair

I guess something like below you after.
IUnityContainer container = new UnityContainer();
container.RegisterType<IKeyMode, KeyMode>(new InjectionConstructor("key1"));
var keyMode = container.Resolve<IKeyMode>();
Console.WriteLine(keyMode.GetKeyMode());

You can pass objects at resolve time by using ResolverOverrides. See Resolving Objects by Using Overrides.
Unity knows how to construct classes so you don't need to register the interface if you don't want to. You could do something like this:
IUnityContainer container = new UnityContainer();
KeyMode keyMode = container.Resolve<KeyMode>(
new ParameterOverride("keyMode", "Key1"));

Related

typescript getter / setter on array property

Is there a good way to use getter / setter pattern for array properties?
For example:
export class User {
private _name: string;
set name(value: string) {
this._name = value;
}
get name(): string {
return this._name;
}
private _roles = new Array<string>();
set roles(value: Array<string>) {
this._roles = value;
}
get roles(): Array<string> {
return this._roles;
}
constructor() {
}
}
While changing user.name fires the setter method, adding or removing items from roles does not.
Now i think i understand why it does not fire the setter, because adding items to the array does not change the pointer but merely adds to the already allocated space (correct me if i'm wrong).
How can we get the desired getter / setter behaviour on array properties?
As you said doing something like user.roles.push('my-role') will merely mutate the existing array. Instead of giving direct access to the array through the roles-setter, you could add methods like addRole and removeRole. Then you can implement whatever logic you need when adding or removing to the roles array, keeping it totally private.

How to sort SourceCache, bind to BindingList, and handle IChangeSets manually with Winforms?

I'm using ReactiveUI 9.21 and DynamicData 6.13 together with WinForms.
I did read https://dynamic-data.org/tag/dynamicdata/ and some other resources, but am still confused with IObservableCache, ReadOnlyObservableCollection and others when dealing with changes in DynamicData collections.
If I have a SourceCache<Result, string> recoResults in a model class - how can I sort it there, and then:
Q1: How do I expose SourceCache to be bound to a BindingList<Result> (in a view model for a view with a DataGridView)?
Q2: At the same time, how do I expose SourceCache to be able to react to IChangeSets manually (in a view with a non-reactive plot component)?
What I have:
In the moment, I expose the SourceCache unsorted as IObservableCache in the model and connect to it the views/view models:
public IObservableCache<Result, string> RecoResults { get; protected set; }
private readonly SourceCache<Result, string> recoResults;
public DropModel()
{
recoResults = new SourceCache<Result, string>(e => e.ID);
RecoResults = recoResults.AsObservableCache();
}
Sorting for the DataGridView's BindingList works in the view model:
ResultBindingList = new BindingList<RecoResult>();
DropModel.RecoResults.Connect()
.Sort(recoResultComparer)
.ObserveOn(RxApp.MainThreadScheduler)
.Bind(ResultBindingList)
.Subscribe();
But I don't know how to do the sorting in the view with the non-reactive plot component:
// Still unsorted results:
var observableResults = VM.DropModel.RecoResults.Connect();
// Add result:
var d2 = observableResults.WhereReasonsAre(ChangeReason.Add)
.ObserveOn(RxApp.MainThreadScheduler)
.ForEachChange(x => {
// Add to plot
})
.Subscribe();
// Remove result:
var d3 = observableResults.WhereReasonsAre(ChangeReason.Remove)
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(_ => {
// Remove from plot
});
What I'd like to have:
I'd like to do the sorting in a central place, because the user can choose between two ways of sorting and I want to sync it in all views. I'd like to expose the sorted results as a single property and use it for the BindingList as well as for manual change iterations.
In the model, I already tried:
public ??? SortedResults { get; protected set; }
recoResults.Connect()
.Sort(recoResultComparer)
.ObserveOn(RxApp.MainThreadScheduler)
.Bind(SortedResults)
.Subscribe();
Q3: What return type is the best to use for SortedResults?
And in general:
Q4: When do we use IObservableCache/IObservableList, and when do we use ReadOnlyObservableCollection? And when is IObservable<IChangeSet<T, key>> used?

.NET Tag Helper to replicate #Html.DisplayFor

I'm discovering .Net Core Tag Helpers and I was just curious to know if there are any tag helpers that replicate the #Html.DisplayFor. I think that the label tag helper replicates #Html.DisplayNameFor since it shows the property name on a model passed to the page, but is there an equivalent for #Html.DisplayFor for displaying a property value?
I'm assuming there isn't because in the microsoft .net core tutorials, razor pages that need to display the property value rather than the property name use the HTML helpers.
First, the tag helper is actually the "label asp-for". You can create a new tag helper that is a "label asp-text" helper.
Another option is to use another tag such as span and create a custom "span asp-for" tag helper.
Here is a simple span implementation:
[HtmlTargetElement("span", Attributes = FOR_ATTRIBUTE_NAME, TagStructure = TagStructure.NormalOrSelfClosing)]
public class CustomSpanTagHelper : InputTagHelper
{
private const string FOR_ATTRIBUTE_NAME = "asp-for";
public CustomSpanTagHelper(IHtmlGenerator generator) : base(generator)
{
}
public override void Process(TagHelperContext context, TagHelperOutput output)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
if (output == null)
{
throw new ArgumentNullException(nameof(output));
}
var metadata = base.For.Metadata;
if (metadata == null)
{
throw new InvalidOperationException(string.Format("No provided metadata " + FOR_ATTRIBUTE_NAME));
}
if (!string.IsNullOrWhiteSpace(metadata.Description))
{
output.Content.Append(metadata.Description);
}
if (metadata.IsEnum)
{
var description = (this.For.Model as Enum).GetDescription();
output.Content.Append(description);
}
base.Process(context, output);
}
}
You will need to register your custom tag helper in your _ViewImports.cshtml like this: (don't forget to rebuild)
#namespace MyProject.Web.Pages
#addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
#addTagHelper MyProject.Web.TagHelpers.CustomSpanTagHelper, MyProject.Web <-- custom import

Custom accessors Eloquent Model

I have a Eloquent Model and I want to create a customized toArray method...
class Posts extends Model {
public function scopeActives($query)
{
return $query->where('status', '=', '1');
}
public function toCustomJS()
{
$array = parent::ToArray();
$array['location'] = someFunction($this->attributes->location);
return $array;
}
}
//In my controller:
Posts::actives()->get()->toArray(); //this is working
Posts::actives()->get()->toCustomJS(); //Call to undefined method Illuminate\Database\Eloquent\Collection::toCustomJS()
How can I override the toArray method or create another "export" method?
get() actually returns a Collection object which contains 0, 1, or many models which you can iterate through so it's no wonder why adding these functions to your model are not working. What you will need to do to get this working is to create your custom Collection class, override the toArray() function, and also override the function in your model responsible for building that collection so it can return the custom Collection object.
CustomCollection class
class CustomCollection extends Illuminate\Database\Eloquent\Collection {
protected $location;
public function __construct(array $models = Array(), $location)
{
parent::__construct($models);
$this->location = $location;
}
// Override the toArray method
public function toArray($location = null)
{
$original_array = parent::toArray();
if(!is_null($location)) {
$original_array['location'] = someFunction($this->location);
}
return $original_array;
}
}
Overriding the newCollection method on your models
And for the models you wish to return CustomCollection
class YourModel extends Eloquent {
// Override the newCollection method
public function newCollection(array $models = Array())
{
return new \CustomCollection($models, $this->attributes['location']);
}
}
Please note this may not be what you are intending. Because a Collection is really just an array of models, it's not good to depend on the location attribute of a single model. Depending on your use-case, it's something that can change from model to model.
It might also be a good idea to drop this method into a trait and then just use that trait in each model you wish to implement this feature in.
Edit:
If you don't want to go through creating a custom Collection class, you can always just do it manually each time...
$some_array = Posts::actives()->get()->toArray();
$some_array['location'] = someFunction(Posts::first()->location);
return Response::json($some_array);

Create UI components on page load

I am currently working on oracle adf task flows and regions and I want to create and update some UI components on page load and for this I am using method call activity as default.The problem is that I am getting null values following is my code in the bean that executes on the method call.
package view;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import oracle.adf.view.rich.component.rich.output.RichOutputText;
public class testBean {
public testBean() {
}
public String testMethod() {
// Add event code here...
FacesContext facesContext = FacesContext.getCurrentInstance();
UIViewRoot root = facesContext.getViewRoot();
RichOutputText text = ( RichOutputText )root.findComponent( "r1:ot1" );
text.setValue( "Adding text on run time" );
return "product";
}
}
The set value method returning me null may be it is because the fragment product.jsff which is the view activity is not initiated and the output text with ot1 returning null.
The better approach to achieve the setting of value is to have a property in your bean say: textValue and then bind the value attribute of your ot1 with the property of the bean.
class TestBean{
private String textValue;
public String testMethod() {
textValue = "Adding text on run time";
}
public String getTextValue(){
return textValue;
}
}
Your JSPX would be:
<af:outputText id="ot1" value=#{beanName.textValue}" />

Resources