Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6743139
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 26, 20262026-05-26T11:55:33+00:00 2026-05-26T11:55:33+00:00

I’m looking at adding taggable functionality to a project I’ve taken on. The project

  • 0

I’m looking at adding taggable functionality to a project I’ve taken on. The project is 3 tier (mvc3 – Domain – Repositories).

I need to add the ability to tag various objects within this system. Because Tags can be attached to many different aggregate roots, I though it best to have tags as their own root (rep / ITagManager in domain).

My Idea was to have an ITaggable interface something similar to:

public interface ITaggable
{
    bool SaveTags(IList<ITag> _tags);
    bool SaveTag(ITag _tag);
    IList<ITag> GetTags();
    bool HasTag(IList<ITag> _tags);
    bool HasTag(ITag _tag);
    bool HasTag(string _tagName);
}

I had the idea to have an ITagManager which has methods to take ITaggable objects and save/load tags attached to them (perhaps using something like String.Concat(typeof(this), this.ID) to generate a unique ID for the object which implements the ITaggable interface).
Now there are two possible routes, first pass in any object that implements the ITaggable interface into the ITagManager itself, or modify the Itaggable interface to something like this:

public interface ITaggable
{
    bool SaveTags(IList<ITag> _tags, ITagManager _tagManager);
    bool SaveTag(ITag _tag, ITagManager _tagManager);
    IList<ITag> GetTags(ITagManager _tagManager);
    bool HasTag(IList<ITag> _tags, ITagManager _tagManager);
    bool HasTag(ITag _tag, ITagManager _tagManager);
    bool HasTag(string _tagName, ITagManager _tagManager);
}

The first solution perhaps smells of anemic model, but the second solution seems messy. I know that dependency could be injected, but I figured having it as a function parameter would make it obvious as to what was going on. Or would it be better to inject it into the object?

Are any of these solutions suitable?

Any help/advice would be appreciated.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-26T11:55:33+00:00Added an answer on May 26, 2026 at 11:55 am

    I don’t think your ‘ITagable’ interface needs to be quite as bloated. Also, I wouldn’t model a Tag as an aggregate root as a tag doesn’t make any sense on its own.

    Here is the interface we use:

    public interface ITagable
    {
        IEnumerable<Tag> Tags { get; }
        void Tag(Tag tag);
        void Untag(Tag tag);
    }
    

    Many of the methods you have on your interface could easily be implemented as extension methods if you required.

    Sometimes you can’t handle all the logic within your domain objects. This is where domain services are useful and is what we use to handle the “processing” of tags on an ‘ITagable’ entity:

    public interface ITagService
    {
        void ProcessTags<TEntity>(TEntity entity, Func<IEnumerable<Tag>> featureTags, 
            string tagString) where TEntity : ITagable;
    }
    

    Notice we pass in the list of ‘featureTags’. In a blog example, this would be the list of tags for the entire blog, since we don’t want to create duplicate tags. The ‘TagService’ therefore, is not doing any kind of persistence, it is just creating new tags (on the blog) if it needs to, and tagging or untagging on the entity if it needs to:

    public class TagService : ITagService
    {      
        public void ProcessTags<TEntity>(TEntity entity, 
            Func<IEnumerable<Tag>> featureTagsFactory, string tagString) where TEntity : ITagable
        {
            var result = new List<Tag>();
            // remove any leading/trailing spaces
            tagString = tagString.Trim();
    
            if (tagString.IsNotNullOrEmpty())
            {
                result.AddRange(from str in tagString.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Where(t => t.Length > 1).Distinct()
                                join tag in featureTagsFactory() on (Slug)str equals tag.Slug into tags
                                from tag in tags.DefaultIfEmpty()
                                select tag ?? new Tag(str.Trim()));
            }
    
            // merge tags
            foreach (var tag in entity.Tags.Except(result)) // remove unmatched tags
            {
                entity.Untag(tag);
            }
            foreach (var tag in result) // entity should check if already added
            {
                entity.Tag(tag);
            }
        }
    }
    

    When we update a tagable entity (normally passing a comma separated list of tags from our UI layer) we do the following:

    // tags
    if (command.TagString.IsNotNullOrEmpty())
    {
        tagService.ProcessTags(post, () => blog.Tags, command.TagString);
    }
    

    In my case, we are mapping all tags to our parent blog object. You’re probably not going to be able to just copy+paste this code but it should give you an idea of how you can handle the processing of tags on your entities.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a jquery bug and I've been looking for hours now, I can't
link Im having trouble converting the html entites into html characters, (&# 8217;) i
I want use html5's new tag to play a wav file (currently only supported
I'm parsing an RSS feed that has an &#8217; in it. SimpleXML turns this
I need to clean up various Word 'smart' characters in user input, including but
I need a function that will clean a strings' special characters. I do NOT
I have thousands of HTML files to process using Groovy/Java and I need to
That's pretty much it. I'm using Nokogiri to scrape a web page what has
I have just tried to save a simple *.rtf file with some websites and
I want to count how many characters a certain string has in PHP, but

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.