> For the complete documentation index, see [llms.txt](https://eleven-fifty-academy.gitbook.io/dotnet-302-core/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://eleven-fifty-academy.gitbook.io/dotnet-302-core/10-messaging/10.1-add-service-method-and-dtos.md).

# 10.1: Add Service Method and DTOs

## Add IMessageService

In your `.Contracts` project, add a new interface called `IMessageService.cs`:

```csharp
public interface IMessageService
{
    Task<Message> GetMessage(int id);
    Task<PagedList<MessageToReturn>> GetMessagesForUser();
    Task<IEnumerable<MessageToReturn>> GetMessageThread(int userId, int recipientId);
    Task<MessageToReturn> CreateMessage(MessageForCreation messageForCreation);
    Task<bool> SaveAll();
}
```

## GetMessage() Method

In your `.Services` project, add a new class called `MessageService.cs`.

Inherit from `IMessageService`, `ctrl + .` and choose `Implement interface`.

For now, we'll just implement the `GetMessage()` and the `SaveAll()` methods. The `CreateMessage()` is much longer and we'll add that after.

```csharp
public class MessageService : IMessageService
{
    private readonly EFConnectContext _context;
    private readonly IUserService _userService;

    public MessageService(EFConnectContext context, IUserService userService)
    {
        _context = context;
        _userService = userService;
    }

    public async Task<Message> GetMessage(int id)
    {
        return await _context.Messages
                        .FirstOrDefaultAsync(m => m.Id == id);
    }

    public Task<PagedList<MessageToReturn>> GetMessagesForUser()
    {
        throw new System.NotImplementedException();
    }

    public Task<IEnumerable<MessageToReturn>> GetMessageThread(int userId, int recipientId)
    {
        throw new System.NotImplementedException();
    }

    public Task<IEnumerable<MessageToReturn>> CreateMessage(MessageForCreation messageForCreation)
    {
        throw new System.NotImplementedException();
    }

    public async Task<bool> SaveAll()
    {
        return await _context.SaveChangesAsync() > 0;
    }
}
```

## Register MessageService

Now, let's register our new service for dependency injection in the `Startup.cs` file in the `.API` project:

```csharp
services.AddScoped<IMessageService, MessageService>();
```

## Add MessageForCreation DTO

In the `.Models` project, add a new folder called `Message`. Inside of that folder, add a new class called `MessageForCreation.cs`:

```csharp
public class MessageForCreation
{
    public int SenderId { get; set; }
    public int RecipientId { get; set; }
    public DateTime DateSent { get; set; }
    public string Content { get; set; }

    public MessageForCreation()
    {
        DateSent = DateTime.Now;
    }
}
```

## Add MessageToReturn DTO

Next, we'll also add a `MessageToReturn` DTO in the same folder:

```csharp
public class MessageToReturn
{
    public int Id { get; set; }
    public int SenderId { get; set; }
    public string SenderKnownAs { get; set; }
    public string SenderPhotoUrl { get; set; }
    public int RecipientId { get; set;}
    public string RecipientKnownAs { get; set; }
    public string RecipientPhotoUrl { get; set; }
    public string Content { get; set; }
    public bool IsRead { get; set; }
    public DateTime? DateRead { get; set; }
    public DateTime DateSent { get; set; }
}
```

## CreateMessage() Method

Now that we have the DTOs, we can implement the `CreateMessage` method in our `MessageService`:

```csharp
public async Task<MessageToReturn> CreateMessage(MessageForCreation messageForCreation)
{
    var sender = await _userService.GetUser(messageForCreation.SenderId);
    var recipient = await _userService.GetUser(messageForCreation.RecipientId);

    var message = new Message
    {
        SenderId = messageForCreation.SenderId,
        RecipientId = messageForCreation.RecipientId,
        DateSent = messageForCreation.DateSent,
        Content = messageForCreation.Content,
        IsRead = false,
        SenderDeleted = false,
        RecipientDeleted = false
    };

    _context.Add(message);

    if (!await SaveAll())
        return null;

    return new MessageToReturn
    {
        Id = message.Id,
        SenderId = message.SenderId,
        SenderKnownAs = message.Sender.KnownAs,
        SenderPhotoUrl = message.Sender.Photos.FirstOrDefault(p => p.IsMain).Url,
        RecipientId = message.RecipientId,
        RecipientKnownAs = message.Recipient.KnownAs,
        RecipientPhotoUrl = message.Recipient.Photos.FirstOrDefault(p => p.IsMain).Url,
        Content = message.Content,
        IsRead = message.IsRead,
        DateRead = message.DateRead,
        DateSent = message.DateSent
    };
}
```

We're getting the recipient and sender `User`s based off the `Id` in the `MessageForCreation` with our `UserService`.

Then we're mapping the `MessageForCreation` to a new `Message` entity for us to save to the database.

Then we're returning *another* mapping - this time from `Message` to `MessageToReturn`.
