In DDD where to keep custom exceptions (application exceptions)? In Infrastructure layer?
Asked Answered
Y

4

19

I'm building a app with following architecture:

UI - Application - Domain - Infrastructure

I have a Application Layer that need use custom exceptions. Where I keep these custom exceptions? In Infrastructure layer? The problem is my Application Layer don't have reference to Infrastructure layer.

What is the correct way?

Update:

Here's my code that throw a exception in Application Layer:

public void InsertNewImage(ImagemDTO imagemDTO)
{
    if (isValidContentType(imagemDTO.ImageStreamContentType))
    {
        string nameOfFile = String.Format("{0}{1}", Guid.NewGuid().ToString(), ContentTypeHelper.GetExtension(imagemDTO.ImageStreamContentType));

        string path = String.Format("{0}{1}", ImageSettings.PathToSave, nameOfFile);

        _fileService.SaveFile(imagemDTO.ImageStream, path);

        Imagem imagem = new Imagem()
                            {
                                Titulo = imagemDTO.Titulo,
                                Descricao = imagemDTO.Descricao,
                                NomeArquivo = nameOfFile
                            };

        _imagemRepository.Add(imagem);

        _dbContext.SaveChanges();
    } else
    {
        throw new WrongFileTypeException(String.Format("{0} is not allowed.", ContentTypeHelper.GetExtension(imagemDTO.ImageStreamContentType)));
    }
}

Even ImageSettings is a ConfigurationSection is in my Application Layer because it uses it. I don't see other way I can transfer my ImageSettings (which should stay in Infrastrucuture Layer) to Infrastructure Layer, someone can help?

public class ImageSettings : ConfigurationSection
{
    /// <summary>
    /// Caminha onde será salvo as imagens
    /// </summary>
    [ConfigurationProperty("pathToSave", IsRequired = true)]
    public string PathToSave
    {
        get { return (string)this["pathToSave"]; }
        set { this["pathToSave"] = value; }
    }

    /// <summary>
    /// Extensões permitidas pra upload
    /// </summary>
    [ConfigurationProperty("allowedExtensions", IsRequired = true)]
    public string AllowedExtensions
    {
        get { return (string)this["allowedExtensions"]; }
        set { this["allowedExtensions"] = value; }
    }

    /// <summary>
    /// Tamanho das imagens
    /// </summary>
    [ConfigurationProperty("imageSize")]
    public ImageSizeCollection ImageSize
    {
        get
        {
            return (ImageSizeCollection)this["imageSize"];
        }
    }
}
Yarn answered 3/10, 2011 at 12:9 Comment(0)
F
4

This is most likely related to your previous question. Exceptions are part of the contract that is defined by application layer and is implemented by infrastructure (DIP and Onion architecture). They should be defined in Appliction terms and handled by Application, but thrown from Infrastructure. For example, in your Application code:

public class NotificationException : Exception {...}

public interface ICanNotifyUserOfSuccessfullRegistration {
    /// <summary>
    /// ...
    /// </summary>
    /// <exception cref="NotificationException"></exception>
    void Notify();
}

And in Infrastructure:

public class SmsNotificator : ICanNotifyUserOfSuccessfullRegistration {
    public void Notify() {
        try {
            // try sending SMS here
        } catch(SmsRelatedException smsException) {
            throw new NotificationException(
                            "Unable to send SMS notification.", smsException);
        }
    }
}
Furriery answered 3/10, 2011 at 15:28 Comment(0)
R
4

In DDD where to keep custom exceptions (application exceptions)? In Infrastructure layer?

  • No

Why?

  • In a Clean Architecture, a center layer never depends on the outside, always the inverse
  • "The fundamental rule is that all code can depend on layers more central, but code cannot depend on layers further out from the core. In other words, all coupling is toward the center.". Please check the article from Jeffrey Palermo.

I've written an article with Onion Architecture with a code sample. Please check this.

But basically, you should add your custom exception to your layer (Application in this case). Just create a folder "Exceptions" and then add your user-defined exception there. Please check this link for my details about how to create user-defined exceptions

Repartee answered 29/8, 2020 at 20:34 Comment(0)
P
0

Do you have a layer where cross-cutting concerns (such as logging or dependency injection) are addressed and which is referenced by all other projects in your solution? If so, this is where youd should put these custom exceptions. I guess that by "infrastructure layer" you actually mean this cross-cutting layer, but if so, it seems strange that your application layer is not referencing it.

Alternatively, you could keep these exceptions in the application layer itself, provided that these exceptions are used only by that layer and perhaps by the UI layer too.

Primogenitor answered 3/10, 2011 at 15:28 Comment(1)
Infrastructure reference Application. Application not reference INfrastructure. I think this is the correct...Yarn
T
0

Acaz Souza - you're incorrect in saying the Application Layer shouldnt reference the Infrastructure Layer. I suggest you read "Domain Driven Design Quickly", which is available for free from InfoQ.

Look at the diagram below, which illustrates my point.

Thanks

Domain Driven Design - Layers

Tevere answered 21/5, 2012 at 15:1 Comment(3)
Hey Ronnie, this diagram is not domain driven design as I understand it to be, it is infrastructure driven.. domain objects (projects) should not have a dependency on infrastructure in DDD.. using ORM to Generate POCO classes and entities doesn't require a project dependency on Infrastructure (Data Access Layer), it is a pre-processing, pre-building concern..Goglet
As far as the application's dependency on Infrastructure is concerned.. that infrastructure seems to encompass concerns beyond the implementation of domain and application services and access to sql servers, gateways, and such.. That is, System.Net.HttpContext is not part of My infrastructure layer, but it is certainly something my application layer has a dependency on. So I can only presume this diagram is designating .net framework assemblies as part of the infrastructure layer. but that isn't infrastructure that is implementing anything in your domain.. so it's dubious..Goglet
In the book "Domain Driven Design Quickly", examples have the application layer referencing the infrastructure layer, e.g. "The application layer is a thin layer which stands between the user interface, the domain and the infrastructure. It interacts with the database infrastructure during login operations...etc" (page 39)Tevere

© 2022 - 2024 — McMap. All rights reserved.