Blazor ProtectedSessionStorage object NULL - c#

I've made a helper class on ProtectedSessionStorage to Read/Write data
using Microsoft.AspNetCore.ProtectedBrowserStorage;
public class SessionObjectHelper
{
[Inject] private ProtectedSessionStorage ProtectedSessionStore { get; set; }
public async Task<string> GetTestProperty()
{
var value = await ProtectedSessionStore.GetAsync<string>("TestProperty") ?? string.Empty;
return value;
}
public async Task SetTestProperty(string value)
{
await ProtectedSessionStore.SetAsync("TestProperty", value);
}
}
If I call any of these methods from a Component as illustrated below, ProtectedSessionStore is always NULL
[Inject] private SessionObjectHelper SessionObjectHelper { get; set; }
protected override async Task OnInitializedAsync()
{
var testProperty= await SessionObjectHelper.GetTestProperty();
}

Your SessionObjectHelper class should declare a constructor to get the injected service, not use the [Inject] attribute, e.g.
public class SessionObjectHelper
{
private ProtectedSessionStorage storage;
public SessionObjectHelper(ProtectedSessionStorage storage)
{
this.storage = storage;
}
The [Inject] attribute is designed to work with Razor Components, not regular classes.
You can then use
[Inject] public SessionObjectHelper SessionObjectHelper { get; set; }
In your component. Note I changed to public - if it's private the runtime won't be able to see/set it.

Related

.NET - It is possible to use DI with the State Pattern?

I'm studying design patterns in .NET and currently i'm trying to implement the State Pattern. But today i got to a problem and i can't figure out how to fix this situation.
I have some state classes, all of them implementing the state interface. One of the last states should connect to a data base, through a service injected by the .NET API Startup class, to persist the data and finish up the process.
The problem is... because of the dependency injection that i need to be in the final state, i can't instanciate this state object to progress to this point. I don't know how to continue from there. I don't know if i'm using the pattern wrong or if the use of dependency injection in this pattern is the problem. I can't give all the details of the problem because my studie's project is a little big mess at this moment, so i made a quick mimic of the structure i'm trying to build in my application.
States interface and the OperatingClass who will execute the state behaviour:
public interface IOperationState
{
public int ExecuteOperation(OperatingClass operatingClass);
}
public class OperatingClass
{
public IOperationState OperationState { get; set; }
public int id { get; set; }
public double value { get; set; }
public OperatingClass(int id) //constructor
{
this.id = id;
value = 0;
OperationState = new StartingState();
}
public int Execute()
{
return OperationState.ExecuteOperation(this);
}
}
Main Service: is the service who my controller calls after receive the API Post Method:
public class MainService
{
public int ExecuteFullOperation(int id)
{
//Receives an id and execute the state transition till the end;
var operatingClass = new OperatingClass(id);
return operatingClass.Execute();
}
}
The classes who represents the states and do the respective actions:
public class StartingState : IOperationState
{
public int ExecuteOperation(OperatingClass operatingClass)
{
// Do something...
operatingClass.OperationState = new MiddleState();
return operatingClass.Execute();
}
}
public class MiddleState : IOperationState
{
public int ExecuteOperation(OperatingClass operatingClass)
{
//Do something with the value... let's supose the result is 123, but it does not matter rn;
operatingClass.value = 123;
//Here is the problem: FinalState needs the PersistenceService, who
//receives a injected class to acess the database;
operatingClass.OperationState = new FinalState();
//I want to execute it and return the sucess or failure of the persistence.
return operatingClass.Execute();
}
}
public class FinalState : IOperationState
{
private readonly IPersistenceService PersistenceService;
public FinalState(IPersistenceService persistenceService)
{
PersistenceService = persistenceService;
}
public int ExecuteOperation(OperatingClass operatingClass)
{
return PersistenceService.PersistData(operatingClass.id, operatingClass.value) ? 200 : 503;
}
}
Additional info: i made the PersistenceService be injected in the Startup.cs as a Transient (i dont know how to make it in another way at this moment).
public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<IPersistenceService, PersistenceService>();
// Irrelevant configurations for the question.
services.AddControllers();
}
Please, help me if you can. I'm having a hard time trying to figure it out by myself.
Thank you for your patience and for your time reading it.
Firstly, we need some simple factory which will supply all necessary dependencies by their type. So let's create types for states:
public enum StateType
{
Start,
Middle,
Final
}
And simple factory:
public class StateFactory
{
private Dictionary<StateType, IOperationState> _stateByType;
// you can inject these dependencies through DI like that:
// public StateFactory(StartingState startingState,
// MiddleState middleState, FinalState finalState,
// PersistenceService persistenceService)
public StateFactory()
{
_stateByType = new Dictionary<StateType, IOperationState>()
{
{ StateType.Start, new StartingState(this) },
{ StateType.Middle, new MiddleState(this) },
{ StateType.Final, new FinalState(new PersistenceService()) }
};
}
public IOperationState GetByType(StateType stateType) =>
_stateByType[stateType];
}
Then we should register all our dependencies:
public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<IPersistenceService, PersistenceService>();
services.AddTransient<StartingState>();
services.AddTransient<MiddleState>();
services.AddTransient<FinalState>();
services.AddTransient<MainService>();
services.AddTransient<OperatingClass>();
services.AddTransient<PersistenceService>();
services.AddTransient<StateFactory>();
}
Our states would look like this:
public class StartingState : IOperationState
{
private StateFactory _factory;
public StartingState(StateFactory stateFactory)
{
_factory = stateFactory;
}
public int ExecuteOperation(OperatingClass operatingClass)
{
// Do something...
// operatingClass.OperationState = new MiddleState();
operatingClass.OperationState = _factory.GetByType(StateType.Middle);
return operatingClass.Execute();
}
}
And MiddleState would look like this:
public class MiddleState : IOperationState
{
private StateFactory _factory;
public MiddleState(StateFactory stateFactory)
{
_factory = stateFactory;
}
public int ExecuteOperation(OperatingClass operatingClass)
{
//Do something with the value... let's supose the result is 123,
// but it does not matter rn;
operatingClass.value = 123;
//Here is the problem: FinalState needs the PersistenceService, who
//receives a injected class to acess the database;
operatingClass.OperationState = _factory.GetByType(StateType.Final);
//I want to execute it and return the sucess or failure of the persistence.
return operatingClass.Execute();
}
}
And Final state should look like this:
public class FinalState : IOperationState
{
private readonly IPersistenceService _persistenceService;
public FinalState(IPersistenceService persistenceService)
{
_persistenceService = persistenceService;
}
public int ExecuteOperation(OperatingClass operatingClass)
{
return _persistenceService
.PersistData(operatingClass.id, operatingClass.value)
? 200
: 503;
}
}
And other classes sush as OperatingClass would use StateFactory too:
public class OperatingClass
{
public IOperationState OperationState { get; set; }
public int id { get; set; }
public double value { get; set; }
public OperatingClass(int id, StateFactory stateFactory) //constructor
{
this.id = id;
value = 0;
// OperationState = new StartingState();
OperationState = stateFactory.GetByType(StateType.Start);
}
public int Execute()
{
return OperationState.ExecuteOperation(this);
}
}
And it is necessary to create concrete example of PersistenceService:
public interface IPersistenceService
{
bool PersistData(int id, double value);
}
public class PersistenceService : IPersistenceService
{
public bool PersistData(int id, double value)
{
throw new NotImplementedException();
}
}

Use Interface to resolve MediatR IRequestHandler instead of the class

I have implement MediatR in .net 5 application and want to resolve require dependencies using Handler interfaces. Currently I using class name to resolve as following
_mediator.Send(new GetDeviceByIMEI(imei)); // want to use interface ??
//var result = await _mediator.Send(IGetHandHeldByIMEI????);
full code reference as following;
Handler Interface
public interface IGetDeviceByIMEIEventHandler
{
Task<DeviceWrapperDataView> Handle(GetDeviceByIMEI request, CancellationToken cancellationToken);
}
Query Interface
public interface IGetDeviceByIMEI
{
string IMEI { get; set; }
}
Query
public class GetDeviceByIMEI: IRequest<DeviceWrapperDataView>
{
public string IMEI { get; set; }
public GetDeviceByIMEI(string imei)
{
this.IMEI = imei;
}
}
Handler
public class GetDeviceByIMEIEventHandler : IRequestHandler<GetDeviceByIMEI, DeviceWrapperDataView>, IGetDeviceByIMEIEventHandler
{
private readonly IDeviceEntity _DeviceEntity;
public GetDeviceByIMEIEventHandler(IDeviceEntity DeviceEntity)
{
_DeviceEntity = DeviceEntity;
}
public async Task<DeviceWrapperDataView> Handle(GetDeviceByIMEI request, CancellationToken cancellationToken)
{
// code to get data
return DeviceOutput;
}
}
API controller
private readonly IMediator _mediator;
public DeviceController(
IMediator mediator)
{
_mediator = mediator;
}
[HttpGet()]
public async Task<IActionResult> GetDeviceByIMEI(string imei)
{
Var result = await _mediator.Send(new GetDeviceByIMEI(imei));
// want to use
}
To do that you have to register your handler in the container with each of the class that inherit your query interface.
For instance with the code you provided.
public interface IGetDeviceByIMEI : IRequest<DeviceWrapperDataView>
{
string IMEI { get; set; }
}
public class GetDeviceByIMEI: IGetDeviceByIMEI
{
public string IMEI { get; set; }
public GetDeviceByIMEI(string imei)
{
this.IMEI = imei;
}
}
public class AnotherGetDeviceByIMEI: IGetDeviceByIMEI
{
public string IMEI { get; set; }
public GetDeviceByIMEI(string imei)
{
this.IMEI = imei;
}
}
public class GetDeviceByIMEIEventHandler : IRequestHandler<IGetDeviceByIMEI, DeviceWrapperDataView>, IGetDeviceByIMEIEventHandler
{
private readonly IDeviceEntity _DeviceEntity;
public GetDeviceByIMEIEventHandler(IDeviceEntity DeviceEntity)
{
_DeviceEntity = DeviceEntity;
}
public async Task<DeviceWrapperDataView> Handle(IGetDeviceByIMEI request, CancellationToken cancellationToken)
{
// code to get data
return DeviceOutput;
}
}
Once you have done that, you have to register the handler in your container with each use case.
For instance in .Net Core, you can do it with the serviceCollection in the StartUp class.
serviceCollection.AddTransient<IRequestHandler<GetDeviceByIMEI, DeviceWrapperDataView>, GetDeviceByIMEIEventHandler >();
serviceCollection.AddTransient<IRequestHandler<AnotherGetDeviceByIMEI, DeviceWrapperDataView>, GetDeviceByIMEIEventHandler >();
Regards.

Umbraco Migration component, datetimeoffset becomes timespan

So i have set up a migration which seems to work fine, the only issues is that my datetimeoffset becomes a timespan in the database, when i run the migration.
And i cannot seem to figure out why, any help would be usefull.
Google and Umbraco forum or documentation have not been very helpfull.
Here is my complete code.
My Schema
public class ArticleLikeSchema
{
[PrimaryKeyColumn(AutoIncrement = true, IdentitySeed = 1)]
[Column("Id")]
public int Id { get; set; }
[Column("Liked")]
public bool Liked { get; set; }
[Column("UmbracoPageId")]
public int UmbracoPageId { get; set; }
[Column("UserID")]
public string UserID { get; set; }
[Column("Created")]
public DateTimeOffset Created { get; set; }
}
My Migration
public class AddArticleLikesTable : MigrationBase
{
private readonly ILogger logger;
public AddArticleLikesTable(IMigrationContext context, ILogger logger) : base(context)
{
this.logger = logger;
}
public override void Migrate()
{
logger.Debug<AddArticleLikesTable>("Running migration {MigrationStep}", "AddArticleCommentsTable");
// Lots of methods available in the MigrationBase class - discover with this.
if (TableExists("ArticleLikes") == false)
{
Create.Table<ArticleLikeSchema>().Do();
}
else
{
logger.Debug<AddArticleLikesTable>("The database table {DbTable} already exists, skipping", "ArticleComments");
}
}
}
And my Component
public class ArticleLikeMigrationComponent : IComponent
{
private readonly ILogger logger;
private readonly IScopeProvider scopeProvider;
private readonly IMigrationBuilder migrationBuilder;
private readonly IKeyValueService keyValueService;
public ArticleLikeMigrationComponent(ILogger logger, IScopeProvider scopeProvider, IMigrationBuilder migrationBuilder, IKeyValueService keyValueService)
{
this.logger = logger;
this.scopeProvider = scopeProvider;
this.migrationBuilder = migrationBuilder;
this.keyValueService = keyValueService;
}
public void Initialize()
{
// Create a migration plan for a specific project/feature
// We can then track that latest migration state/step for this project/feature
var likesMigrationPlan = new MigrationPlan("ArticleLikes");
// This is the steps we need to take
// Each step in the migration adds a unique value
likesMigrationPlan.From(string.Empty)
.To<AddArticleLikesTable>("Article-Like-migration");
// Go and upgrade our site (Will check if it needs to do the work or not)
// Based on the current/latest step
var upgrader2 = new Upgrader(likesMigrationPlan);
upgrader2.Execute(scopeProvider, migrationBuilder, keyValueService, logger);
}
public void Terminate()
{
}
}
What are you trying to do? If you want a date, you could use DateTime instead?
[Column(TypeName="DateTime")]
public DateTime Created { get; set; }
You could also try:
public class AddExtraColumns : MigrationBase
{
public AddExtraColumns(IMigrationContext context) : base(context) {}
public override void Migrate()
{
Create.Column("Created").OnTable("gfdgdf").AsDate(50).Nullable().Do();
}
}

How to access class properties through an Interface instance using Unity.WebApi

Is it possible to expose class public properties in different class through IOC. I am creating an instance of Interface but i am not able to access public properties of class. I am using Unity.WebApi for resolving dependencies.
TransactionService Class
public class TransactionService : ITransactionService
{
private readonly IMRepository _mRepository;
private readonly IFService _fGateway;
public TransactionService(IMbaRepository mbaRepository, IFpnService fpnService)
{
_mRepository = mRepository;
_fGateway = fService;
}
private List<Transaction> SearchTransacionsByUser(FUser objFUser)
{
foreach (var item in something)
{
//can't use _fGateway to set properties because Interface
// don't implement them
_fGateway.OID = objFUser.OID.ToString();
_fGateway.Amount = objFUser.Amount;
_fGateway.Search(criteria);
}
}
}
FService class
public class FService : IFpService
{
public string _OID { get; set; }
public decimal _Amount{ get; set; }
public TransactionResponse Search(string criteria)
{
TransactionOperationInput _input;
_input = new TransactionOperationInput()
{
Criteria = _criteria,
OID = _OID,
Amount = _Amount
};
// search transactions
}
}
If you are in control of the services then refactor the interfaces to expose the desired members
public interface IFService {
TransactionResponse Search(TransactionOperationInput input);
}
Make sure the derived implementation has those members
public class FService : IFpService {
public TransactionResponse Search(TransactionOperationInput input) {
// search transactions
}
}
And that the dependent class uses the correct abstraction
public class TransactionService : ITransactionService {
private readonly IMRepository _mRepository;
private readonly IFService fGateway;
public TransactionService(IMbaRepository mbaRepository, IFService fService) {
_mRepository = mRepository;
fGateway = fService;
}
private List<Transaction> SearchTransacionsByUser(FUser objFUser) {
foreach (var item in something) {
TransactionOperationInput input = new TransactionOperationInput() {
Criteria = _criteria,
OID = objFUser.OID.ToString(),
Amount = objFUser.Amount,
};
fGateway.Search(input);
//...
}
//...
}
}
Finally make sure the register the appropriate abstractions and implementations with the IoC/DI container.

Avoid Casting in following Code by using Generics

I am new to generics and just wondering if it's possible to avoid the casting in the following code using better OO approach.
public class CollectorFactory
{
public static MyCollector Create(ICredential credential)
{
return new MyCollector(credential);
}
}
public class MyCollector {
public MyCredential Credential { get; set; }
public MyCollector(ICredential credential)
{
this.Credential = (MyCredential)credential;
}
public void Show()
{
Console.WriteLine(this.Credential.Username);
Console.WriteLine(this.Credential.AuthToken);
}
}
public class MyCredential : ICredential
{
public string Username{ get; set; }
public string AuthToken { get; set; }
}
public interface ICredential
{
}
Is there a way to save the casting of ICredential to MyCredential in MyCollector's Constructor? I don't have option to put Username and AuthToken in ICredential as it's implemented by two different Credentials that both have different set of properties. CollectorFactory will be returning different MyCollector instances in the future and both need to have different credentials.
Any help would be really appreciated.
I don't think it's possible given that you're implementing different credentials and trying to use them for ICredential as well.
Here is a way of doing this using generics. Please read my comments in the code.
public class CollectorFactory<T>
{
public T Create(ICredential credential)
{
return (T)Activator.CreateInstance(typeof(T), credential);
}
}
public class MyCollector : BaseCollector
{
public dynamic Credential { get; private set; }
public MyCollector(ICredential credential)
: base(credential)
{
this.Credential = credential;
}
// Having this method here limits your ability to make it more generic.
// Consider moving this to MyCredential since it refers to specific properties in MyCredential.
// If that is not what you want, then you must do a type check before calling methods/ accessing props in Credentials.
public void Show()
{
Console.WriteLine(this.Credential.Username);
Console.WriteLine(this.Credential.AuthToken);
}
}
public class MyCredential : ICredential
{
public string Username { get; set; }
public string AuthToken { get; set; }
}
public abstract class BaseCollector : ICredentialCollector
{
protected BaseCollector(ICredential credential)
{
if (credential == null)
{
throw new ArgumentNullException(nameof(credential));
}
}
}
public interface ICredentialCollector
{
}
public interface ICredential
{
}
// test implementation
public class TestClass
{
public void AuthFactoryTest()
{
// test auth instance
MyCredential auth = new MyCredential() {AuthToken = "asfgasdgdfg", Username = "xuser"};
// Create test factory
var fact = new CollectorFactory<MyCollector>();
var myCollector = fact.Create(auth);
// Do what you need to do to collector object
myCollector.Show();
}
}
Generics isn't the solution in this case. The issue here is that your factory is returning a specific type (MyCollector). A solution around this would be the following:
public class CollectorFactory
{
public static ICollector Create(MyCredential credential)
{
return new MyCollector(credential);
}
public static ICollector Create(OtherCredential credential)
{
return new OtherCollector(credential);
}
}
public interface ICollector
{
void Show();
}
public class MyCollector : ICollector
{
public MyCredential Credential { get; set; }
public MyCollector(MyCredential credential)
{
this.Credential = credential;
}
public void Show()
{
Console.WriteLine(this.Credential.Username);
Console.WriteLine(this.Credential.AuthToken);
}
}
public class MyCredential : ICredential
{
public string Username{ get; set; }
public string AuthToken { get; set; }
}
public interface ICredential
{
}
The above is pretty much the canonical example of the Factory design pattern.
Instead of overloads you could also do typechecking in the factory:
public class CollectorFactory
{
public static ICollector Create(ICredential credential)
{
if(credential.GetType() == typeof(MyCredential))
return new MyCollector((MyCredential) credential);
if(credential.GetType() == typeof(OtherCredential ))
return new OtherCollector((OtherCredential ) credential);
}
}

Categories