C
C#2y ago
Sh1be

Accessing data from another project

Hello, so I have 2 projects, one is an app that contains some data and the other project is a web api that is supposed to pull data from that first project. I tried achieving that by implementing an interface for the first project which i then add to the web api's dependency injection with the implementation pointing to the first project main file. So everytime i try to access data now from the running service (it has the data) in the web api, it just returns null. why is that happening?
63 Replies
sibber
sibber2y ago
with the implementation pointing to the first project main file.
wdym by this and how are you "accessing the data"
TheBoxyBear
TheBoxyBear2y ago
The client and api projects shouldn't reference each other, create a third project for common definitions
Sh1be
Sh1be2y ago
public class Bot : IBackupBot
{
private DiscordShardedClient discord;

// main class etc. where discord gets initialised and bot starts running

public Task<string> Test()
{
return Task.FromResult(discord.ShardClients[0].Guilds[0].Name);
}
}
public class Bot : IBackupBot
{
private DiscordShardedClient discord;

// main class etc. where discord gets initialised and bot starts running

public Task<string> Test()
{
return Task.FromResult(discord.ShardClients[0].Guilds[0].Name);
}
}
Test() is in IBackupBot web api:
var builder = WebApplication.CreateBuilder(args);
builder.Services
.AddSingleton<IBackupBot, Bot>();

var app = builder.Build();
var xd = (IBackupBot)app.Services.GetService(typeof(IBackupBot))!;

app.MapGet("/test", () => xd.Test());
var builder = WebApplication.CreateBuilder(args);
builder.Services
.AddSingleton<IBackupBot, Bot>();

var app = builder.Build();
var xd = (IBackupBot)app.Services.GetService(typeof(IBackupBot))!;

app.MapGet("/test", () => xd.Test());
trying to go to /test shows an error saying discord is null but its getting initialised and is running at the same time
sibber
sibber2y ago
store this discord.ShardClients[0].Guilds[0].Name in a variable an put a breakpoint after it check if it returns what you expect
Sh1be
Sh1be2y ago
Sh1be
Sh1be2y ago
i realized Guilds[0] wouldnt work cause it used the guild id as key so i did .first but it still has the same problem
sibber
sibber2y ago
discord was null
Sh1be
Sh1be2y ago
yep thats the problem, but it clearly is able to start up
Sh1be
Sh1be2y ago
Sh1be
Sh1be2y ago
its getting initialised before too @Cyberrex sorry for the ping but do you have an idea what could fix this?
pip
pip2y ago
the bot appears as online when you launch it? it only returns null when you do the api req?
Sh1be
Sh1be2y ago
Yep its online and being able to handle commands as well so its running properly Only somehow turns null when doing the api req yes
pip
pip2y ago
try something for me store your sharded clients in memory well actually nvm, that should work regardless
Sh1be
Sh1be2y ago
It should work regardless yeah Ive even tried using the assembly property [assembly:InternalsVisibleTo("WebApi")] and still no luck
pip
pip2y ago
does this maybe have something to do with discord being accessed by that conn thread? just spitballing here
Sh1be
Sh1be2y ago
Hmm i dont think it would make it null then It shouldnt suddenly invalidate the variable that created it if that were the case Does anyone have an idea? And that would work?
TheBoxyBear
TheBoxyBear2y ago
It won't fix it on its own but it's something you should consider instead of referencing the client directly
Sh1be
Sh1be2y ago
Well i could do that But i still need a fix I dont want to give up on the project cause of that
TheBoxyBear
TheBoxyBear2y ago
When you do that, the entire client build is included with the api so it's more bloated and prevents you from having multiple clients for various platforms
Sh1be
Sh1be2y ago
What do you mean? Im making a discord bot and im just also making a web api for it
TheBoxyBear
TheBoxyBear2y ago
You mentionned the other project is an app, that's the client
Sh1be
Sh1be2y ago
Yep, the discord bot But i dont understand what you are trying to say
TheBoxyBear
TheBoxyBear2y ago
By referencing a file from another project, do you mean a data file like json or txt or a cs file defining a class to model the data?
Sh1be
Sh1be2y ago
Its the instance of a running discordshardedclient from which i want to get the data from
TheBoxyBear
TheBoxyBear2y ago
So to have that model in both projects, that's where the Common project comes in A class library that contains models used by both classes. Each project has it pointing to the same class file without the project containing extra things it doesn't need Then just serialize the instance you want to send and deserialize to the same model on the other end
Sh1be
Sh1be2y ago
So id have a 3rd project that contains a discordshardedclient and the 1st project (bot) just uses the instance in the 3rd project?
TheBoxyBear
TheBoxyBear2y ago
Yes, each project needs an implementation of it, not just an interface. If you have the implementation in the client, the entire client will be included in the api build
Sh1be
Sh1be2y ago
How would i do that?
TheBoxyBear
TheBoxyBear2y ago
Just make a class library project containing the interface and implementation and each the other projects reference the library If it's all in the same solution, you can add it as a project reference easily in VS
Sh1be
Sh1be2y ago
Oh i see so should i do the whole implementation of the bot in that class library or only declaring it there and implementing it from the 1st project still?
TheBoxyBear
TheBoxyBear2y ago
Only the data models used by both projects
Sh1be
Sh1be2y ago
So basically only the discord client
TheBoxyBear
TheBoxyBear2y ago
You could also make it a shared project instead so the classes are directly included in the assembly instead of compiling to a standalone dll
Sh1be
Sh1be2y ago
To make it clear now, in the 3rd project which will be a class library i will just have an attribute thats a discord client and then initialize it and start it from the 1st project but also reference it in the 3rd project so i can access it in the web api?
TheBoxyBear
TheBoxyBear2y ago
If the DiscordClient class also does thing on top of storing data, then you should make a class just for the data
Sh1be
Sh1be2y ago
Nope it doesnt I just want to be able to access the client's methods through the web api
TheBoxyBear
TheBoxyBear2y ago
Then it's a different issue. If you want to access the methods to call them, then the api would be doing things outside its scope
Sh1be
Sh1be2y ago
Well id use the methods to get data like for example roles or member count etc Trying to do this didnt work
TheBoxyBear
TheBoxyBear2y ago
Where do you initialize discord?
Sh1be
Sh1be2y ago
In the 1st project in Bot.cs In the Bot class
TheBoxyBear
TheBoxyBear2y ago
So Test gets called on the api. You should see what is in xd after you create the service
Sh1be
Sh1be2y ago
xd is being implemented here
TheBoxyBear
TheBoxyBear2y ago
There's also a generic extension GetService method so you don't have to cast
Sh1be
Sh1be2y ago
I registered the bot in dependency injection and got an instance of it in xd But trying to call it then failed vecause discord was somehow null That is the main issue And i see
TheBoxyBear
TheBoxyBear2y ago
You only create a service for the Box class, it won't inject a DiscordSharedClient
Sh1be
Sh1be2y ago
Well the implementation for the interface i registered is in the Bot class which creates and has the discordshardedclient in it So it shouldnt be null
TheBoxyBear
TheBoxyBear2y ago
Hard to tell without the full code You can double check what's in discord after it's created And what's in it through xd when the service is created
Sh1be
Sh1be2y ago
Bot.cs
public class Bot : IBackupBot
{
private DiscordShardedClient discord;

internal async Task MainAsync()
{
discord = new DiscordShardedClient(new DiscordConfiguration()
{
Token = discordConfig.Token,
TokenType = TokenType.Bot,
Intents = DiscordIntents.AllUnprivileged | DiscordIntents.GuildMembers | DiscordIntents.MessageContent | DiscordIntents.GuildMessages,
MinimumLogLevel = LogLevel.Information,
LoggerFactory = new LoggerFactory().AddSerilog(Log.Logger),
ServiceProvider = serviceProvider,
});
await discord.StartAsync();
await Task.Delay(-1);
}
public Task<string> Test()
{
return Task.FromResult(discord.ShardClients[0].Guilds.First().Value.Name);
}
public class Bot : IBackupBot
{
private DiscordShardedClient discord;

internal async Task MainAsync()
{
discord = new DiscordShardedClient(new DiscordConfiguration()
{
Token = discordConfig.Token,
TokenType = TokenType.Bot,
Intents = DiscordIntents.AllUnprivileged | DiscordIntents.GuildMembers | DiscordIntents.MessageContent | DiscordIntents.GuildMessages,
MinimumLogLevel = LogLevel.Information,
LoggerFactory = new LoggerFactory().AddSerilog(Log.Logger),
ServiceProvider = serviceProvider,
});
await discord.StartAsync();
await Task.Delay(-1);
}
public Task<string> Test()
{
return Task.FromResult(discord.ShardClients[0].Guilds.First().Value.Name);
}
IBackupBot.cs
public interface IBackupBot
{
Task<string> Test();
}
public interface IBackupBot
{
Task<string> Test();
}
Program.cs of web api
var builder = WebApplication.CreateBuilder(args);
builder.Services
.AddSingleton<IBackupBot, Bot>();

var app = builder.Build();

var xd = (IBackupBot)app.Services.GetService(typeof(IBackupBot))!;

app.MapGet("/test", () => xd.Test("ss"));

app.Run();
var builder = WebApplication.CreateBuilder(args);
builder.Services
.AddSingleton<IBackupBot, Bot>();

var app = builder.Build();

var xd = (IBackupBot)app.Services.GetService(typeof(IBackupBot))!;

app.MapGet("/test", () => xd.Test("ss"));

app.Run();
@TheBoxyBearfull code basically the relevant things
TheBoxyBear
TheBoxyBear2y ago
What library are you using for discord?
Sh1be
Sh1be2y ago
that doesnt really matter but im using DisCatSharp (https://github.com/Aiko-IT-Systems/DisCatSharp)
TheBoxyBear
TheBoxyBear2y ago
Trying to find the docs for DiscordSharedClient. It's under what namespace6
TheBoxyBear
TheBoxyBear2y ago
The api doesn't call MainAsync
Sh1be
Sh1be2y ago
the 1st project's Program.cs calls it hthough
TheBoxyBear
TheBoxyBear2y ago
In the first project yes, but that Main doesn't get called in the api It's two different programs running individually
Sh1be
Sh1be2y ago
Sh1be
Sh1be2y ago
i thought that it would still be able to access one another
TheBoxyBear
TheBoxyBear2y ago
That's just telling VS to run both when you hit Start The build is two folders each with its own exe
Sh1be
Sh1be2y ago
i thought that through dependency injection it would be possible somehow so the solution to that would be to have a class library with a discordshardedclient in it that gets initialized in the 1st project and being able to used in the web api project too then? or how should i make it work then
TheBoxyBear
TheBoxyBear2y ago
Each process exists in a bubble with it's own object instances Even if they share the same class, that's just the processes reading the model from a dll file.
Sh1be
Sh1be2y ago
so could i somehow achieve what i want?
TheBoxyBear
TheBoxyBear2y ago
You need some form of irc to pass data between the projects. Since one is an api, the easiest would be serializing the data and passing it through a web socket Could make it an endpoint in the api to receive the data from the client If they run on the same machine, you can set up the client to connect to localhost and can easily change that down the road if you deploy on standalone machines
Sh1be
Sh1be2y ago
oh guess ill make a websocket then thank you for your help man i thought it would be possible just through DI hahah