Is ReSharper supposed to provider pop-up intellisense documentation for items that use the tag when you hover over a usage of that item?
If so, it's not working for me - at least, not consistently. Using ReSharper Ultimate 2018.1.3
public interface IFoo
{
/// <summary>
/// Gets or sets the value of Bar
/// </summary>
int Bar { get; set; }
}
public class FooImpl : IFoo
{
#region Implementation of IFoo
/// <inheritdoc />
public int Bar { get; set; }
#endregion
}
public class TestFooImpl
{
public void Test()
{
var foo1 = new FooImpl
{
Bar = 3
};
}
}
When I hover over a reference to FooImpl.Bar, I don't get any useful pop-up Intellisense:
But when I do ctrl+shift+F1:
ReSharper is configured to override the usual VS intellisense behavior:
Related
I have a Blazor page with two components. One component has a button which generates a random number when clicked. The other component has a text area which should display the generated random number.
<h1>Parent Page</h1>
<ProvideNumberComponent />
<DisplayNumberComponent />
#code {
}
<h3>Provides Number</h3>
<button class="btn btn-primary" #onclick="CalculateNumber">Provide Number</button>
#code {
private void CalculateNumber(MouseEventArgs e)
{
Random rnd = new Random();
Int32 nextNumber = rnd.Next();
}
}
<h3>Displays number</h3>
<textarea cols="9" rows="1" readonly style="font-family:monospace;" />
#code {
}
What is the cleanest way to get the number from the calculate sibling component to appear in the display sibling component?
A problem with my code is that the Random object is instantiated on every button click, instead of once on initialization. Is this best addressed by placing the Random object in a singleton service class, and injecting that into the calculate component?
The best solution, to my mind, is to create a service which implements the state pattern and the notifier pattern. The following code describes how communication between two sibling can be done through an intermediary
NotifierService.cs
public class NotifierService
{
public NotifierService()
{
}
int rnd;
public int RandomNumber
{
get => rnd;
set
{
if (rnd != value)
{
rnd= value;
if (Notify != null)
{
Notify?.Invoke();
}
}
}
}
public event Func<Task> Notify;
}
Add this: services.AddScoped<NotifierService>();
ProvideNumberComponent.razor
#inject NotifierService Notifier
#implements IDisposable
<h3>Provides Number</h3>
<button class="btn btn-primary" #onclick="CalculateNumber">Provide
Number</button>
#code
{
private void CalculateNumber(MouseEventArgs e)
{
Random rnd = new Random();
Int32 nextNumber = rnd.Next();
Notifier.RandomNumber = nextNumber;
}
public async Task OnNotify()
{
await InvokeAsync(() =>
{
StateHasChanged();
});
}
protected override void OnInitialized()
{
Notifier.Notify += OnNotify;
}
public void Dispose()
{
Notifier.Notify -= OnNotify;
}
}
DisplayNumberComponent.cs
#inject NotifierService Notifier
#implements IDisposable
<hr />
<h3>Displays number</h3>
<textarea cols="9" rows="1" readonly style="font-family:monospace;">
#Notifier.RandomNumber
</textarea>
#code {
public async Task OnNotify()
{
await InvokeAsync(() =>
{
StateHasChanged();
});
}
protected override void OnInitialized()
{
Notifier.Notify += OnNotify;
}
public void Dispose()
{
Notifier.Notify -= OnNotify;
}
}
Of course you can inject and use the service in multiple components, as well as adding more features that the service can provide.
Implementing communication by means of event handlers may be problematic, unless it is between a parent and its child...
Hope this works...
Indeed there are many ways to accomplish your goal, I just want to show you the way I like more:
Parent Component:
<EditForm Model="Message">
<PageOne #bind-Send="Message.Text"/>
<PageTwo #bind-Receive="Message.Text"/>
</EditForm>
#code{
public Content Message { get; set; }=new Index.Content();
public class Content
{
public string Text { get; set; } = "Hello world";
}
}
PageOne component - the one who send the value:
<button #onclick="#GetGuid">Change value</button>
#code{
[Parameter] public string Send { get; set; }
[Parameter] public EventCallback<string> SendChanged { get; set; }
async void GetGuid()
{
await SendChanged.InvokeAsync(Guid.NewGuid().ToString());
}
}
PageTwo the component which will receive the data
<h1>#Receive</h1>
#code{
[Parameter] public string Receive { get; set; }
[Parameter] public EventCallback<string> ReceiveChanged { get; set; }
}
Explanations:
Usually when we need to communicate, we need a third party service, and in this case I used the EditForm component, which can store a Model and the properties of this model can be shared by all child components.
I also made a custom component, with less functionality, and I named PhoneBox (to be used instead EditForm), just to be obvious the role :)
PhoneBox - third party communication service :)
<CascadingValue Value="EditContext">
#ChildContent(EditContext)
</CascadingValue>
#code {
[Parameter] public object Model { get; set; }
[Parameter]public EditContext EditContext { get; set; }
[Parameter] public RenderFragment<EditContext> ChildContent { get; set; }
protected override void OnInitialized()
{
EditContext = new EditContext(Model);
}
}
I like more this approach because look's more "blazor way" :)
Look how nice is "blazor way"
<PhoneBox Model="Message">
<PageOne #bind-Send="Message.Text"/>
<PageTwo #bind-Receive="Message.Text"/>
</PhoneBox>
You can see a working example Working Example
I think interfaces are the best way to do this.
This is from my Nuget package, DataJugger.Blazor.Components
Interface IBlazorComponent:
#region using statements
using System.Collections.Generic;
#endregion
namespace DataJuggler.Blazor.Components.Interfaces
{
#region interface IBlazorComponent
/// <summary>
/// This interface allows communication between a blazor componetn and a parent component or page.
/// </summary>
public interface IBlazorComponent
{
#region Methods
#region ReceiveData(Message message)
/// <summary>
/// This method is used to send data from a child component to the parent component or page.
/// </summary>
/// <param name="data"></param>
void ReceiveData(Message message);
#endregion
#endregion
#region Properties
#region Name
/// <summary>
/// This property gets or sets the Name.
/// </summary>
public string Name { get; set; }
#endregion
#region Parent
/// <summary>
/// This property gets or sets the Parent componet or page for this object.
/// </summary>
public IBlazorComponentParent Parent { get; set; }
#endregion
#endregion
}
#endregion
}
Interface IBlazorComponentParent
#region using statements
using System.Collections.Generic;
#endregion
namespace DataJuggler.Blazor.Components.Interfaces
{
#region interface IBlazorComponentParent
/// <summary>
/// This interface is used to host IBlazorComponent objects
/// </summary>
public interface IBlazorComponentParent
{
#region Methods
#region FindChildByName(string name)
/// <summary>
/// This method is used to find a child component that has registered with the parent.
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
IBlazorComponent FindChildByName(string name);
#endregion
#region ReceiveData(Message message)
/// <summary>
/// This method is used to send data from a child component to the parent component or page.
/// </summary>
/// <param name="data"></param>
void ReceiveData(Message message);
#endregion
#region Refresh()
/// <summary>
/// This method will call StateHasChanged to refresh the UI
/// </summary>
void Refresh();
#endregion
#region Register(IBlazorComponent component)
/// <summary>
/// This method is called by the Sprite to a subscriber so it can register with the subscriber, and
/// receiver events after that.
/// </summary>
void Register(IBlazorComponent component);
#endregion
#endregion
#region Properties
#region Children
/// <summary>
/// This property gets or sets the value for Children.
/// </summary>
public List<IBlazorComponent> Children { get; set; }
#endregion
#endregion
}
#endregion
}
For usage, here is the most relevant parts:
In your component, which is an IBlazorCompoent (child), there is a Parent property.
In your component, you set the parent like this:
<Login Parent=this></Login>
Then in your component, you alter the parent property like this:
[Parameter]
public IBlazorComponentParent Parent
{
get { return parent; }
set
{
// set the value
parent = value;
// if the Parent exists
(Parent != null)
{
// Register with the parent
Parent.Register(this);
}
}
}
Next, in your parent component that implements IBlazorComponentParent, add a property for your component and change the Register method to this:
// Login component reference
public Login LoginComponent { get; set; }
public void Register(IBlazorComponent component)
{
if (component is Login)
{
// Store the LoginComponent
LoginComponent = component as Login;
}
else if (component is Join)
{
// Store the compoent
SignUpComponent = component as Join;
}
}
Now at this point, my Login component knows about the parent and the parent knows about the Login, so I can sent messages like this:
From the child, send a simple message:
if (Parent != null)
{
Message message = new Message();
message.Text = "Some message";
Parent.SendMessage(message);
}
Or send a complex message
// create a message
DataJuggler.Blazor.Components.Message message = new DataJuggler.Blazor.Components.Message();
// Create the parameters to pass to the component
NamedParameter parameter = new NamedParameter();
// Set the name
parameter.Name = "PixelInformation Update";
parameter.Value = pixel;
// Create a new collection of 'NamedParameter' objects.
message.Parameters = new List<NamedParameter>();
// Add this parameter
message.Parameters.Add(parameter);
// Send this to the component
ColorPickerComponent.ReceiveData(message);
Then in the parent to receive the message:
public void ReceiveData(Message message)
{
// If the message object exists and has parameters
if ((message != null) && (message.HasParameters))
{
// if this a PixelInformation update from the Index page
if (message.Parameters[0].Name == "PixelInformation Update")
{
// this is only relevant to my app, just showing an example of
// \what I do with the data after it is received.
// Set the SelectedPixel
SelectedPixel = (PixelInformation) message.Parameters[0].Value;
// Set the properties from the Pixel to display
SetupColorPicker();
}
}
}
The above code is used in my newest site, PixelDatabase.Net https://pixeldatabase.net
The Nuget package code is all open source if anyone wants it:
DataJuggler.Blazor.Components
https://github.com/DataJuggler/DataJuggler.Blazor.Components
I come from a Windows Forms background, so I love being able to communicate between components like this, which data binding doesn't always work.
this.Login.DoSomething(data);
You can also cast the parent as a specific type like this:
public IndexPage ParentIndexPage
{
get
{
// cast the Parent object as an Index page
return this.Parent as IndexPage;
}
}
So your child can call methods or set properties on the parent, if the parent exists of course, so always add a:
public bool HasParentIndexPage
{
get
{
// return true if the ParentIndexPage exists
return (ParentIndexPage != null);
}
}
So then for easy usage from the child:
// if the parent index page exists
if (HasParentIndexPage)
{
// Safely call your parent page
ParentIndexPage.SomeMethod();
}
On way to do it would absolutely be to use the session pattern and inject the same instance in both components and then notify them onchange. A faster way would probably be to use the two way binding and eventcallbacks.
In ProvideNumberComponent.razor
<button class="btn btn-primary" #onclick="CalculateNumber">Provide Number</button>
#code {
[Parameter]
public EventCallback<int> OnRandomNumberSet{get; set;}
private void CalculateNumber(MouseEventArgs e)
{
Random rnd = new Random();
Int32 nextNumber = rnd.Next();
OnRandomNumberSet.InvokeAsync(nextNumber);
}
}
In ParentComponent.razor
<h1>Parent Page</h1>
<ProvideNumberComponent OnRandomNumberSet="((r) => SetRandomNumber(r))"/>
<DisplayNumberComponent TextAreaValue="_randomNumber" />
#code {
private int _randomNumber;
private void SetRandomNumber(int randomNumber)
{
_randomNumber = randomNumber;
}
}
In DisplayNumberComponent.razor
<h3>Displays number</h3>
<textarea cols="9" rows="1" bind:value="TextAreaValue" readonly style="font-family:monospace;" />
#code
{
[Parameter]
public int TextAreaValue{get; set;}
}
MDSN has an example using DI injected Notifier service
invoke component methods externally to update state, which should work for any component-relation (not only siblings).
At a steeper learning curve, but more maintenance-friendly + scaleable in the long run is the Flux/Redux library Fluxor
For anyone trying to get an overview of more "design-pattern"'ish solutions, MVVM is also a posibility, example here: MVVM example implementation 4 Blazor
ServiceStack self host windows service question, at the link there are two Services: TodoService.cs and HelloService.cs.
I am a little confused, are they different examples or related each other?
//Register REST Paths
[Route("/todos")]
[Route("/todos/{Id}")]
public class Todo //REST Resource DTO
{
public long Id { get; set; }
public string Content { get; set; }
public int Order { get; set; }
public bool Done { get; set; }
}
//Todo REST Service implementation
public class TodoService : RestServiceBase<Todo>
{
public TodoRepository Repository { get; set; } //Injected by IOC
public override object OnGet(Todo request)
{
if (request.Id == default(long))
return Repository.GetAll();
return Repository.GetById(request.Id);
}
//Called for new and update
public override object OnPost(Todo todo)
{
return Repository.Store(todo);
}
public override object OnDelete(Todo request)
{
Repository.DeleteById(request.Id);
return null;
}
}
And
/// <summary>
/// Define your ServiceStack web service request (i.e. the Request DTO).
/// </summary>
[Description("ServiceStack's Hello World web service.")]
[Route("/hello")]
[Route("/hello/{Name*}")]
public class Hello
{
public string Name { get; set; }
}
/// <summary>
/// Define your ServiceStack web service response (i.e. Response DTO).
/// </summary>
public class HelloResponse : IHasResponseStatus
{
public string Result { get; set; }
public ResponseStatus ResponseStatus { get; set; }
}
/// <summary>
/// Create your ServiceStack web service implementation.
/// </summary>
public class HelloService : ServiceBase<Hello>
{
protected override object Run(Hello request)
{
return new HelloResponse { Result = "Hello, " + request.Name };
}
}
They are separate examples of different services you can build with ServiceStack. The ServiceStack examples are made available in a single solution called ServiceStack.Examples, but it contains separate projects.
You are looking in a directory called StarterTemplates.Common, this is simply shared by several of the examples for code reusability. The folder structure does not indicate that TodoService.cs and HelloService.cs are directly related.
The individual projects of the ServiceStack Examples, can be seen here.
Backbone.js TODO app with REST and Redis backend
Creating a Hello World Web service from scratch
Here is what I want to be happened. I am working on a Win Forms application. I want a class to run first then store values in a different class which has a struct in it which holds a value. Now when the Form frmMainConsole loads I want it to read the values from the struct to set certain properties on the form.
Here is what I have tried:
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new frmMainConsole());
}
here is the class with the struct:
public class MyAppSetting
{
//View Setting
public bool ShowMoves { get; set; }
}
Now when the frmMainConsoleLoads which is here:
private void frmMainConsole_Load(object sender, EventArgs e)
{
CreateGroupBox();
//Set Initial Settings
MyAppSetting MyAppSetting = new ChessStrategyGame.MyAppSetting();
movesToolStripMenuItem.Checked = MyAppSetting.ShowMoves;
}
Now the class I want to use to start the application looks like this:
class StartUp
{
public static void Main()
{
MyAppSetting MyAppSetting = new MyAppSetting();
MyAppSetting.ShowMoves = true;
//On the Main Form of application
Form frmMainConsole = new frmMainConsole();
frmMainConsole.Show();
}
}
Basically I want the application to remember certain settings from the last time it was run
My issue:
A custom validation attribute is called twice and not once when calling a webapi post method (with EF) - I am not sure if this is normal and would like a definitive answer. It validates at the following points:
Just before the breakpoint enters the webapi application post method (presumably populating ModelState)
Again just before the insert takes place (db.Applications.Add(application))
[Table("Applications")]
public class Application
{
/// <summary>
/// ApplicationID (auto-increment)
/// </summary>
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int ApplicationID { get; set; }
/// <summary>
/// Name of the application
/// </summary>
[Required]
[MaxLength(255)]
public string ApplicationName { get; set; }
/// <summary>
/// Application ref (for friendly lookups)
/// </summary>
[Required]
[MaxLength(150)]
[UniqueApplicationReference] // <<<<<<< My custom validation attribute
public string ApplicationRef { get; set; }
/// <summary>
/// Application status
/// </summary>
[Required]
public bool? ApplicationStatus { get; set; }
public virtual ICollection<ApplicationFeature> ApplicationFeatures { get; set; }
}
Here is my webAPI end point:
public HttpResponseMessage PostApplication(Application application)
{
if (ModelState.IsValid)
{
db.Applications.Add(application);
db.SaveChanges();
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created, application);
response.Headers.Location = new Uri(Url.Link("DefaultApi", new { id = application.ApplicationID }));
return response;
}
else
{
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
}
}
Is the better solution simply to provide a Data Transfer class for application object with little/simple validation on it for the purposes of passing the data and then let any domain specific validation errors just bubble back via HttpResponseMessage therefore lookups are only run when the insert is attempted with reasonable data?
Thank you!
Dan.
A base class, VideoContainer, contains a list of VideoContainers.
The properties in VideoContainer are common to three other classes of which there are three:
Layout
Perspective
Source
Each of these classes have different properties, and should fit inside the VideoContainers collection.
/// <summary>
/// Video container
/// </summary>
public class VideoContainer<T>
{
/// <summary>
/// Container ID
/// </summary>
public int Id { get; set; }
/// <summary>
/// Type of container - {Layout, Perspective, SourceContainer}
///
/// This is usually set by the instantiated class.
/// </summary>
public ContainerTypes ContainerType { get; set; }
/// <summary>
/// Parent ID
/// </summary>
public VideoContainerIdentifier ParentObject { get; set; }
/// <summary>
/// Name of container
/// </summary>
public string Name { get; set; }
/// <summary>
/// Details about the physical location of this container
/// </summary>
public LocationDefinition LocationDefinition { get; set; }
/// <summary>
/// When container has a tile applied - number of rows of containers within this perspective
/// </summary>
public short NumRows { get; set; }
/// <summary>
/// When container has a tile aplpied - the number of columns of containers within this perspective
/// </summary>
public short NumColumns { get; set; }
/// <summary>
/// List of containers
/// </summary>
public IList<VideoContainer<T>> VideoContainers { get; set; }
/// <summary>
/// Draw
/// </summary>
public virtual void Draw()
{
// drawing tasks
}
}
The initial problem was that I couldn't put a Layout (or other class type) inside the VideoContainers collection, as it expects a type of VideoContainer.
So I added <T>, hoping but having problems accessing the properties of type <T> - which doesn't work.
How can I set this up properly?
-- UPDATE --
What I forgot to mention is that the classes all inherit VideoContainers.
As per the suggestion below, I created public interface IVideoContainer<T>.
The Layout class is now defined as public class Layout : IVideoContainer<Layout> and implements all of the interface's methods:
public class Layout : IVideoContainer<Layout>
{
/// <summary>
/// ctor
/// </summary>
public Layout()
{
ContainerType = ContainerTypes.Layout;
}
public int Id
{...
Problem is in implementing:
var layout = new IVideoContainer<Layout>
{
Id = 1,
ParentObject = null,
Name = "Layout Definition 1",
LocationDefinition = new LocationDefinition
{
TopLeftX = 0,
TopLeftY = 0,
WidthPixels = 1000,
HeightPixels = 1000
},
NumRows = 20,
NumColumns = 20,
VideoContainers = new List<Perspective>
{
new IVideoContainer<Perspective>
{
Id = 10, ...
-- Update 2 --
I now have:
/// <summary>
/// VideoContainer
/// </summary>
/// <typeparam name="T"></typeparam>
public class VideoContainer<T> : IVideoContainer
{
public int Id { get; set; }
public ContainerTypes ContainerType { get; set; }
public VideoContainerIdentifier ParentObject { get; set; }
public string Name { get; set; }
public LocationDefinition LocationDefinition { get; set; }
public short NumRows { get; set; }
public short NumColumns { get; set; }
public IList<IVideoContainer> VideoContainers { get; set; }
}
The issue is that SourceContainer contains new properties, which I cannot access - CctvId and StreamUri:
VideoContainers = new List<VideoContainer<SourceContainer>>
{
new VideoContainer<SourceContainer>
{
Id = 20,
ParentObject = new VideoContainerIdentifier
{
Id = 10,
ContainerType = ContainerTypes.Perspective
},
ContainerType = ContainerTypes.SourceContainer,
CctvId = new Guid(),
StreamUri = new Uri("http://127.0.0.1/somestream"),
LocationDefinition = new LocationDefinition // TODO: verify that {x,y} are relative to the perspective
{
TopLeftX = 0,
TopLeftY = 0,
WidthPixels = 10,
HeightPixels = 10
}
},
SourceContainer class:
public class SourceContainer : IVideoContainer
{
/// <summary>
/// the URI of the stream for this source
/// </summary>
public Uri StreamUri { get; set; }
/// <summary>
/// the descriptive name of this source
/// </summary>
//public string Name { get; set; }
/// <summary>
/// optional device id for this source
/// </summary>
public Guid? CctvId { get; set; }
/// <summary>
/// ctor
/// </summary>
public SourceContainer()
{
ContainerType = ContainerTypes.SourceContainer;
}
public int Id { get; set; }
public ContainerTypes ContainerType { get; set; }
public VideoContainerIdentifier ParentObject { get; set; }
public string Name { get; set; }
public LocationDefinition LocationDefinition { get; set; }
public short NumRows { get; set; }
public short NumColumns { get; set; }
public IList<IVideoContainer> VideoContainers { get; set; }
}
Create an Interface that collects the common properties, have your three classes inherit from it, and then cast your T to the Interface to access the properties.
public class VideoContainer: IVideoContainer
{
public List<IVideoContainer> Children { get; set; }
}
If you want to access properties specific to the object you're storing in the List, just cast it to the original object:
var child = Children.First();
var type = m.GetType();
if(type.Name == "ChildClass")
{
var container = (ChildClass)child;
// Now you can access VideoContainer specific properties in `container`.
}