forevolve / forevolve-framework Goto Github PK
View Code? Open in Web Editor NEWA .NET Standard 2.1 Toolbox (a.k.a. .NET Core 3+, .NET 5)
License: MIT License
A .NET Standard 2.1 Toolbox (a.k.a. .NET Core 3+, .NET 5)
License: MIT License
Calling AddForEvolveOperationResults
in Startup.ConfigureServices
should load OperationResults and its dependencies; implicitly calling AddForEvolveErrorFactory
instead of throwing the following exception:
InvalidOperationException: Unable to resolve service for type 'ForEvolve.AspNetCore.IErrorFactory' while attempting to activate 'ForEvolve.AspNetCore.DefaultOperationResultFactory'.
fast-build
(filter -Trait:"Dependency"
) and a full-build
(no filter)SUPPORT_AZURE_EMULATOR
and favor the use of traitsOperationResult.Failure(Exception)
should support inner exceptions.
ex.InnerException != null
add the exception to the error collection.Reason: it is not strictly related to APIs.
When an IOperationResult
is in the scope of a Controller
(http request), it should automatically populate its ModelState
with the error messages instead of doing it "manually" everytime.
IObjectModelValidator
to populate the ModelState
ModelStateDictionaryExtensions.AddModelErrorFrom()
?Should be able to send from a specific email account.
Interface
Add the following method to IEmailSenderService
:
Task SendEmailAsync(MailAddress email, string subject, string message);
Task SendEmailAsync(string senderEmail, string recipientEmail, string subject, string message);
Task SendEmailAsync(MailAddress senderEmail, string recipientEmail, string subject, string message);
Task SendEmailAsync(MailAddress senderEmail, MailAddress recipientEmail, string subject, string message);
Implementation (DefaultEmailSenderService
)
In the case that a method with a senderEmail
is called, replace EmailOptions.SenderEmailAddress
by the specified senderEmail
.
Since the pipeline can be configured anyway, this boolean only creates confusion.
This feature aim at testing operation execution order.
Example:
As a consumer, I'd like to set up the code like this, allowing the declaration code to be written only once; but also allowing multiple declarations to support all use cases:
private readonly _operationRegister = new MoqOperationRegister();
//...
_someMock
.SetupWithMonitoring(operationRegister, x => x.SomeCall(It.IsAny<string>())
.Returns(true);
_someOtherMock
.SetupWithMonitoring(operationRegister, x => x.SomeOtherCall());
//...
Then in the tests, I'd like something like this to verify the outcome:
// Arrange
var operationMonitor = _operationRegister .CreateMonitor();
//...
// Act
Act();
// Assert
Assert.Collection(
operationMonitor.Operations,
operation => Should_do_something_clever(
operation,
expectedParameters: new { paramName = "some string" },
expectedResult: true
),
operation => Should_do_something_even_more_clever(operation)
);
The MoqOperationRegister instance should not be shared between tests run in parallel execution. The idea here is only to save time by declaring all the monitored operations once.
In the previous code sample, operation
would be an instance of a class similar to this:
public class MonitoredOperation
{
public MonitoredOperation(string name, dynamic value = null)
{
Name = name ?? throw new ArgumentNullException(nameof(name));
Time = DateTime.UtcNow;
Value = value;
}
public string Name { get; }
public DateTime Time { get; }
public dynamic Value { get; }
}
Name
is the operation name; this could be converted to something else than a string.Time
is the execution time, allowing to monitor execution time as well.Value
is a dynamic
object holding the arguments as properties, allowing to test input as well as output and execution order.See if it is possible to implement a non generic IFilterableTableStorageReader
that support ReadAsync<TModel>(...)
instead of the class level generic TModel
.
The ITableStorageSettings
is usually injected in the class constructor; See how to solve this.
Add and implement a ITableStorageRepositoryFactory
to help lower the number of dependencies injected in classes.
Early implementation/idea:
public interface ITableStorageRepositoryFactory
{
ITableStorageRepository<TModel> CreateRepository<TModel>() where TModel : class, ITableEntity, new();
IFilterableTableStorageReader<TModel> CreateReader<TModel>() where TModel : class, ITableEntity, new();
}
public class TableStorageRepositoryFactory : ITableStorageRepositoryFactory
{
private readonly IServiceProvider _serviceProvider;
public TableStorageRepositoryFactory(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider));
}
public ITableStorageRepository<TModel> CreateRepository<TModel>()
where TModel : class, ITableEntity, new()
{
return _serviceProvider.GetService<ITableStorageRepository<TModel>>();
}
public IFilterableTableStorageReader<TModel> CreateReader<TModel>()
where TModel : class, ITableEntity, new()
{
return _serviceProvider.GetService<IFilterableTableStorageReader<TModel>>();
}
}
Describe the bug
When referencing ForEvolve.App
the rasterize.js
file (from PDF) seems to be copying itself at the project root and in the PhantomJs/Root/
directory.
To Reproduce
Steps to reproduce the behavior:
ForEvolve.App
packageExpected behavior
rasterize.js
should only be present in the PhantomJs/Root/
directory.
Additional context
Version: ForEvolve.*-RC-1
Create TableQuery
helpers like StartWith
.
Maybe something chainable like that: query.Column("ColName").StartWith("String to check")
; TBD.
See #9
ForEvolve.OperationResults.AspNetCore
(review this, maybe creating a standalone project would be best?)ExceptionTransformer
that could map specific exception type(s) to an IOperationResult
allowing customization of the exception convention pipeline. This could be based on, use, or update the concepts of IOperationResultStandardizer
.ExceptionTransformer
should support returning any type, no just IOperationResult
, making this compatible with any system (including, but not limited to, my old DynamicInternalServerError
projcet).AddForEvolveOperationResultFilters()
extension method or create an AddForEvolveOperationResultApiFilters()
method to differentiate API filters vs MVC filters (or both); TODO: review/rename these to be more generic and less "OperationResult-centric".OperationResult-centric stuff could be part of another assembly, following an assembly structure similar to:
ForEvolve.ExceptionFilters.Abstraction
ForEvolve.ExceptionFilters.AspNetCore
( or ForEvolve.ExceptionFilters.AspNet
)ForEvolve.ExceptionFilters.AspNetCore.OperationResults
ForEvolve.ExceptionFilters.AspNetCore.DynamicInternalServerError
(maybe?)ForEvolve.ExceptionFilters.MediatR
(or ForEvolve.ExceptionFilters.VerticalSlice
)ForEvolve.ExceptionFilters.MediatR.OperationResults
ForEvolve.ExceptionFilters.MediatR.DynamicInternalServerError
(maybe?)Notes to self
feature/application-insights
ForEvolve.Azure
or not; based on the dependencies brought by ApplicationInsights.
ForEvolve.Azure
must target netstandardX.Y
, not netcoreappX.Y
.netcoreappX.Y
but should aim at netstandardX.Y
.ForEvolve.ApplicationInsights
ForEvolve.ApplicationInsights
to ForEvolve.Azure\ApplicationInsights
in a new branch feature/application-insights
.master
.TraitAttribute
to tests that use the Azure Storage Emulatornetstandard2.0
CODE_OF_CONDUCT
and CONTRIBUTING
; create ISSUE_TEMPLATE
s
ForEvolve.AspNetCore.UserIdFinder
directoryForEvolve.AspNetCore.Middleware
directoryForEvolve.AspNetCore.HttpRequestValueFinder
directory; atm, the implementation only look into request headers.
services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
toservices.AddHttpContextAccessor()
in ForEvolveAspNetCoreStartupExtensions.csAddHttpRequestValueFinder()
extension method that encapsulate both adding IHttpRequestValueFinder
elements and the IHttpContextAccessor
; allowing to not load the IHttpContextAccessor
if not used (for performance gain). Validate where IHttpContextAccessor
is used in the project to se if it is possible.CodeCoverage
dependency ForEvolvePdfNuGetExperiment
to a new ForEvolve.Samples
repo)services.Add*
to services.AddForEvolve*
when required.services.Configure*
to services.ConfigureForEvolve*
when required.ForEvolve.DynamicInternalServerError
and ForEvolve.DynamicInternalServerError.Swagger
READMEForEvolve.Pdf.PhantomJs.Dependencies
project to its own repository to keep this one lighter.nuget.org
Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
Describe the solution you'd like
A clear and concise description of what you want to happen.
Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.
Additional context
Add any other context or screenshots about the feature request here.
Here are some notes about the test server development and the XUnit test project.
See #10
Create an easy to use, modular, programmable, per test (or per test class), in-memory mock server.
v1.1.0
?).ForEvolve.TestApp
and ForEvolve.TestApp.XUnit
.Update or remove classes like HttpTestServerBuilder
and HttpTestServer
and use the new asp.net 2.1 Microsoft.AspNetCore.Mvc.Testing
instead as a fondation.
Check if it is possible to support both .net core 2.0 and 2.1 without too much effort. If it isnt possible, target 2.1 and implement support for 2.0 later.
Split the remaining elements of this issue after cleaning up #10
Allow easy testing of IOperationResult
with default failure message.
Examples:
result.AssertSuccess(); // Failure message: The operation should be sucessful.
result.AssertFailure(); // Failure: The operation should not be sucessful.
result.AssertFailure(
error => Assert.Equal("Some expected error message 1", error.Message),
error => Assert.Equal("Some expected error message 2", error.Message),
error => Assert.Equal("Some expected error message ...", error.Message),
error => Assert.Equal("Some expected error message N", error.Message)
);
// Failure: The operation should not be sucessful.
// Collection failure: report (do not handle) Assert.Collection() error
When doing:
var x = new EmailOptions();
x.Smtp
should not be null
.
Ideas:
IOperationResult
like string GetMessage()
or IEnumerable<string> GetMessages()
to ease the access to messages.string Message { get; }
property on IMessage
that link to the appropriate dictionary key; this must not be serialized.Implemented diverse type transformation methods and extensions instead.
For example, find ans use a IMessage
of the MyBadMessage
type:
if (!result.Succeeded && result.Messages.Contains<MyBadMessage>())
{
// Do something with that!
MyBadMessage message = result.Messages.GetSingle<MyBadMessage>();
if (message.SomeProp == "Toto!")
{
// ...
}
// ...
}
Or, find all ArgumentNullException
:
IEnumerable<ArgumentNullException> exceptions = result.Messages.GetExceptionsOfType<ArgumentNullException>();
// Do something with "exceptions"
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.