How to get first or guardian actor in akka.net? - akka.net

Edit : Executive summary: Where the bleep is 'Sys' defined? I see it in Akka.net code all over the internet, but my build is not finding it. Who or what do I have to import, use, link, do, bribe or kill?
Should be screamingly easy. Taking first steps in Akka.net, the sample does not build. This was copied from the [Getting Started example][1]
[1]: https://getakka.net/articles/intro/tutorial-1.html . It does not build, because 'Sys' is not defined. This obviously elementary step is nowhere described on their site, and I've given up on tweak-n-try.
Here is all of the code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MyAkka
{
class Program
{
public class PrintMyActorRefActor : UntypedActor
{
protected override void OnReceive(object message)
{
switch (message)
{
case "printit":
IActorRef secondRef = Context.ActorOf(Props.Empty, "second-actor");
Console.WriteLine($"Second: {secondRef}");
break;
}
}
}
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
var firstRef = Sys.ActorOf(Props.Create<PrintMyActorRefActor>(), "first-actor");
Console.WriteLine($"First: {firstRef}");
firstRef.Tell("printit", ActorRefs.NoSender);
Console.ReadKey();
}
}
}

Here is a working version of your code:
using System;
using Akka.Actor;
namespace SysInAkkaNet
{
class Program
{
public class PrintMyActorRefActor : UntypedActor
{
protected override void OnReceive(object message)
{
switch (message)
{
case "printit":
IActorRef secondRef = Context.ActorOf(Props.Empty, "second-actor");
Console.WriteLine($"Second: {secondRef}");
break;
}
}
}
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
using (var actorSystem = ActorSystem.Create("MyActorSystem"))
{
var firstRef = actorSystem.ActorOf(Props.Create<PrintMyActorRefActor>(), "first-actor");
Console.WriteLine($"First: {firstRef}");
firstRef.Tell("printit", ActorRefs.NoSender);
Console.ReadKey();
}
}
}
}
You need to create an actor system to put your actors in. And you need to add a reference to the Akka NuGet package, and a corresponding using Akka.Actor; statement.
I know that the Akka.TestKit has a property Sys, which gives you a reference to the actor system that is created for a given test.
Apart from that, I am not able to answer why the documentation you are referring to shows these "Sys.ActorOf(...)" examples like that (with a capital S), indicating that it is a (possibly built-in) property, so I kind of understand your confusion there.

Related

Why does 'InputField' not contain a definition for 'text'?

I'm currently working on a Unity project for a college assignment, and I'm currently trying to connect a login/registration through PlayFab into a teammate's main menu for the game.
I've connected the PlayFabManager.cs script to the Input Fields for the email and password in the Unity editor, and something about my InputFields.cs file is preventing me from making any more progress.
I had to change the passwordInput and emailInput variables to TMP_InputField variables to achieve this, but now I am getting a compilation error in my project that says the following:
Assets\Scripts\InputField.cs(13,24): error CS1061: 'InputField' does not contain a definition for 'text' and no accessible extension method 'text' accepting a first argument of type 'InputField' could be found (are you missing a using directive or an assembly reference?)
Most places I look have people not including the "using UnityEngine.UI;" header at the top of the file, but that's included in my InputField.cs file.
Here's the code for my InputField.cs file:
using UnityEngine;
using System.Collections;
using UnityEngine.UI; // Required when Using UI elements.
public class InputField : MonoBehaviour
{
public InputField mainInputField;
public void Start()
{
mainInputField.text = "Enter text here...";
}
}
Here's the code for my PlayFabManager.cs file:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using PlayFab;
using PlayFab.ClientModels;
using Newtonsoft.Json;
using UnityEngine.UI;
using TMPro; // Needed for login input fields
public class PlayFabManager : MonoBehaviour
{
[Header("UI)")]
public Text messageText;
public TMP_InputField emailInput;
public TMP_InputField passwordInput;
// Register/Login/ResetPassword
public void RegisterButton() {
var request = new RegisterPlayFabUserRequest {
Email = emailInput.text,
Password = passwordInput.text,
RequireBothUsernameAndEmail = false
};
PlayFabClientAPI.RegisterPlayFabUser(request, OnRegisterSuccess, OnError);
}
void OnRegisterSuccess(RegisterPlayFabUserResult result) {
messageText.text = "Registered and Logged in";
}
public void LoginButton() {
}
// Start is called before the first frame update
void Start() {
Login();
}
// Update is called once per frame
void Login() {
var request = new LoginWithCustomIDRequest {
CustomId = SystemInfo.deviceUniqueIdentifier,
CreateAccount = true
};
PlayFabClientAPI.LoginWithCustomID(request, OnSuccess, OnError);
}
void OnSuccess(LoginResult result) {
Debug.Log("Successful login/account create.");
}
void OnError(PlayFabError error) {
Debug.Log("Error while loggin in/creating account.");
Debug.Log(error.GenerateErrorReport());
}
}
I would just remove the InputField.cs class as it fixes my errors, but it changes the functionality of the following code that my teammate has contributed:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class MenuControl : MonoBehaviour
{
public string newGameLevel;
public void NewUser() {
SceneManager.LoadScene(newGameLevel);
}
public void ExitButton() {
Application.Quit();
}
}
Any help would be much appreciated!
Wanted to provide the solution in case this happens to anyone in the future:
I solved the problem by changing the
public InputField mainInputField;
into an input variable that could receive the TMP_Imput like so: public TMPro.TMP_InputField mainInputField;

Confusion over using generic repository in .NET Core 6

I'm developing services with a micro service architecture using .NET Core 6. I'm trying to follow clean architecture advice and have created 3 layers, Core (I put my use cases, repository interfaces, and my dto models), API layer, and infrastructure (connection with DB and implementation of repository interfaces).
The problem is the number of repositories is increasing, because I'm creating a separate repository for each different job, for example IStoreCarPricesRepository, IStoreCarSparePartRepository,..... I was thinking, would it not be wiser to have a generic repository and and just create a class to call it and do the jobless say you are getting different messages from different queues and was to store them in the respective tables?
As far as I searched for generic repository is kind of outdated, I would appreciate your comments
Yes, you can use Generic repository:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Data;
using System.Data.Entity;
using ContosoUniversity.Models;
using System.Linq.Expressions;
namespace DAL
{
public class GenericRepository<TEntity> where TEntity : class
{
internal SchoolContext context;
internal DbSet<TEntity> dbSet;
public GenericRepository(SchoolContext context)
{
this.context = context;
this.dbSet = context.Set<TEntity>();
}
public virtual IEnumerable<TEntity> Get(
Expression<Func<TEntity, bool>> filter = null,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
string includeProperties = "")
{
IQueryable<TEntity> query = dbSet;
if (filter != null)
{
query = query.Where(filter);
}
foreach (var includeProperty in includeProperties.Split
(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{
query = query.Include(includeProperty);
}
if (orderBy != null)
{
return orderBy(query).ToList();
}
else
{
return query.ToList();
}
}
public virtual TEntity GetByID(object id)
{
return dbSet.Find(id);
}
public virtual void Insert(TEntity entity)
{
dbSet.Add(entity);
}
public virtual void Delete(object id)
{
TEntity entityToDelete = dbSet.Find(id);
Delete(entityToDelete);
}
public virtual void Delete(TEntity entityToDelete)
{
if (context.Entry(entityToDelete).State == EntityState.Detached)
{
dbSet.Attach(entityToDelete);
}
dbSet.Remove(entityToDelete);
}
public virtual void Update(TEntity entityToUpdate)
{
dbSet.Attach(entityToUpdate);
context.Entry(entityToUpdate).State = EntityState.Modified;
}
}
}
Then you can instantiate and use it for each table:
private GenericRepository<Department> departmentRepository;
private GenericRepository<Employee> employeeRepository;
Read more about generic repositories here.
Repo doesn't works with jobs and messages.
The main responsibility of repository is a wrapper for common operations (CRUD) or maybe some work with tables for example count, any, some, all.
If you wish to create a microservice architecture, it is useful to check generic repositories in GitHub and create your own library and move the generic-repository here. It should be something like YourName.Microservice.Core.
After that, connect it through a nuget-extension to your Microservice.Core.
In the future, you need to extend them to avoid a duplication of code in a lot of microservices.

Fody MethodDecorator not working

I am trying to create a method decorator using Fody but it gives me the following error:
I have taken specific care to not wrap my IMethodDecorator inside any namespace as has been mentioned in a lot of places online. Following is the sample code I am trying in a console app.
IMethodDecorator
using System;
using System.Reflection;
public interface IMethodDecorator
{
void OnEntry(MethodBase method);
void OnExit(MethodBase method);
void OnException(MethodBase method, Exception exception);
}
MethodDecoratorAttribute
using System;
using System.Diagnostics;
using System.Reflection;
using FODYPOC;
// Atribute should be "registered" by adding as module or assembly custom attribute
[module: MethodDecorator]
namespace FODYPOC
{
// Any attribute which provides OnEntry/OnExit/OnException with proper args
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Assembly | AttributeTargets.Module)]
public class MethodDecoratorAttribute : Attribute, IMethodDecorator
{
// instance, method and args can be captured here and stored in attribute instance fields
// for future usage in OnEntry/OnExit/OnException
public MethodDecoratorAttribute() { }
public void OnEntry(MethodBase method)
{
Console.WriteLine();
}
public void OnExit(MethodBase method)
{
Console.WriteLine();
}
public void OnException(MethodBase method, Exception exception)
{
Console.WriteLine();
}
}
public class Sample
{
[MethodDecorator]
public void Method()
{
Debug.WriteLine("Your Code");
}
}
}
Can someone point me in the right direction. It looks pretty simple to implement and I know I am making a very silly mistake somewhere.
Apparently the latest version of MethodDecorator.Fody (Version 0.9.0.6 currently) was not working. Downgrading the version to version 0.8.1.1 fixed the issue for me.
After a little more investigation, it appears that the interface method signatures were different in the two versions. So when I had the new package, it was not expecting MethodBase as a parameter and due to not finding anything that matches the interface it expects, it was throwing the error.

Instantiate using Windsor's factory

Below's code is working fine, and successfully create an instance for class DummyComponnent.
But the problem arises when i had changed the factory method name CreatDummyComponnent()
to GetDummyComponnent() or anything else except Creat as the beginning of method name, say AnyThingComponent throws an exception. is there any specify naming rule for factory methods ?
using System;
using Castle.Facilities.TypedFactory;
using Castle.MicroKernel.Registration;
using Castle.Windsor;
namespace AsFactoryImplementation
{
public interface IDummyComponnentFactory
{
IDummyComponnent CreatDummyComponnent();
// void Relese(IDummyComponnent factory);
}
public interface IDummyComponnent
{
void Show();
}
public class DummyComponnent:IDummyComponnent
{
public DummyComponnent()
{
Console.WriteLine("we are working here");
}
public void Show()
{
Console.WriteLine("just testing this for better performance");
}
}
class Program
{
static void Main(string[] args)
{
var container = new WindsorContainer();
container.AddFacility<TypedFactoryFacility>();
container.Register(Component.For<IDummyComponnent>().ImplementedBy<DummyComponnent>().Named("FirstConnection"),
Component.For<IDummyComponnentFactory>().AsFactory());
var val = container.Resolve<IDummyComponnentFactory>();
var iDummy = val.CreatDummyComponnent();
iDummy.Show();
Console.WriteLine("OK its done ");
Console.ReadLine();
}
}
}
You should be able to use anything for starting the method names on the Factory, except for starting with Get.
If you start with Get it will try to resolve the component by name instead of by interface.
So what would work in your example is:
var iDummy = val.GetFirstConnection();
Good luck,
Marwijn.

Using PostSharp OnExceptionAspect across mulit projects

Good afternoon everyone,
I am trying to use the example "Aspect Oriented Programming Using C# and PostSharp" by Reza Ahmadi
http://www.codeproject.com/Articles/337564/Aspect-Oriented-Programming-Using-Csharp-and-PostS and dnrTV http://dnrtv.com/dnrtvplayer/player.aspx?ShowNum=0190 for the exception handling. Everything works great if the "OnExceptionAspect" is in the same project/assembly, however the event does not work if it I move the class to it own dll.
[assembly: ExceptionAspect (AttributePriority = 1)]
[assembly: ExceptionAspect(AttributePriority = 2, AttributeExclude = true, AttributeTargetTypes = "HpsErp.Common.AspectObject.*")]
namespace AspectObject
[Serializable]
public class ExceptionAspect : OnExceptionAspect
{
public override void OnException(MethodExecutionArgs args)
{
Trace.TraceError("{0} in {1}.{2}",
args.Exception.GetType().Name,
args.Method.DeclaringType.FullName,
args.Method.Name);
if (args.Instance != null)
{
Trace.TraceInformation("this={0}", args.Instance);
}
foreach (ParameterInfo parameter in args.Method.GetParameters())
{
Trace.TraceInformation("{0}={1}", parameter.Name,
args.Arguments[parameter.Position] ?? "null");
}
}
I also created a class in the external dll for "Timing" and it works great if I add a custom attribute to the class.
namespace AspectObject
[Serializable]
[MulticastAttributeUsage(MulticastTargets.Method)]
public class TimingAspect : OnMethodBoundaryAspect
{
[NonSerialized]
Stopwatch _StopWatch;
public override void OnEntry(MethodExecutionArgs args)
{
_StopWatch = Stopwatch.StartNew();
base.OnEntry(args);
}
public override void OnExit(MethodExecutionArgs args)
{
Console.WriteLine(string.Format("[{0}] took {1}ms to execute",
new StackTrace().GetFrame(1).GetMethod().Name,
_StopWatch.ElapsedMilliseconds));
base.OnExit(args);
}
Using AspectObject;
namespace MyApp
{
public class Car
{
[TimingAspect]
private void Drive()
{
//...
}
}
}
In the end, I am hoping to have this is multi dlls so that I can reuse it ie: wcf.
Thanks for any and all help...
James
You can access your aspects if they are stored in a separate DLL.
I always create a DLL class project called Aspects. In the projects I want AOP, I add a reference to that dll class. Then decorate your methods/class/assembly like you normally do.
https://github.com/sharpcrafters/PostSharp-Toolkits <-- good examples
http://researchaholic.com/tag/postsharp/ <-- some more examples, just uploaded an example