小编Oni*_*mus的帖子

工人调度算法

问题

这是我想要解决的问题的本质.在周末,我们有工人在托儿所照顾孩子.一个周末有16个不同的插槽可供填写.因此,对于为期4周的月份,有64个插槽可供填充.我们最多有30名托儿所工人(虽然我们需要更多.像孩子一样的人?).

编辑:每个时段都是离散的 - 它们不重叠.

目前有一个人每个月都会提出托儿所时间表.每个月根据每个人的喜好制定这个时间表是一项复杂而耗时的任务.在考虑了这个问题后,我心想,"必须有一个更好的方法!"

算法

我注意到问题基本上是一个二分图.在婚姻问题也是一个二分图,您可以通过使用像匹配算法解决埃德蒙兹的匹配算法.

但是这假设一个节点集中的每个节点仅匹配另一个节点集中的一个节点.就我而言,每个托儿所工作者只能工作一个时间段.由于我们严重缺乏人手,这是行不通的!一群人每个月必须工作两次才能填满所有时间段.

这似乎意味着这更像是经典的"医院/居民问题".它与婚姻问题的不同之处在于,"女性"可以接受来自不止一个"男人"的"建议"(例如,医院可以接纳多个居民).在我的情况下,托儿所工人可以占用多个时间段.

现在怎么办?

呼!

现在我已经完成了设置....有没有人知道任何解释或显示这种算法的好链接?有没有更好的方法来解决这个问题?我在想它吗?我做了一个谷歌搜索"医院居民算法",并找到了研究生的论文.尔加!我毕业于CS学位并参加了AI课程......但那是6年前的事了.救命!

Aaaaany建议表示赞赏!!

algorithm scheduling constraints graph matching

11
推荐指数
1
解决办法
4377
查看次数

加载程序集而不锁定文件并保留正确的绑定上下文

我已经克服了一个令人生畏的难题.这是我的情况:

我正在使用插件框架构建应用程序.有一个基本插件类,所有插件都必须扩展.在同一个程序集中,我有一个帮助程序类,它将序列化和反序列化类.它是一个通用类,它遍布各处.结构是这样的:

MyApp.dll
|_ App.cs
|_ HelperCollection.cs
|_ PluginBase.cs

MyPlugin.dll
|_MyPlugin.cs (this extends PluginBase)
|_Foo.cs
Run Code Online (Sandbox Code Playgroud)

问题

我的问题是程序集加载和锁定文件.该应用程序的一个要求是可以随时覆盖插件.如果是这样,他们需要重新加载.这似乎是加载程序集以使其不被锁定的最佳方式(也就是说,我可以在应用程序仍在运行时覆盖它或吹走)是这样的:

byte[] readAllBytes = File.ReadAllBytes("MyPlugin.dll");
Assembly assembly = Assembly.Load(readAllBytes);
Run Code Online (Sandbox Code Playgroud)

加载插件组件工作正常,没有问题.我从插件程序集中的MyPlugin.cs中得到一个例外,我试图使用它HelperCollection进行反序列化.一个例子可能是这样的:

// HelperCollection uses XmlSerializer under the covers
List<Foo> settingCollection = HelperCollection<Foo>.Deserialize("mysettings.xml");
Run Code Online (Sandbox Code Playgroud)

它正在爆炸并抛出一个InvalidCastException说法"Unable to cast object of type 'List[Foo]' to 'List[Foo]'".经过多次研究,我终于找到了原因.它被加载到LoadNeither绑定上下文中.

何时Foo加载(来自MyPlugin.dll)它位于LoadNeither绑定上下文中,而包含类型转换类型的程序集(在我的情况下,MyApp.dll)在Default上下文中加载.因此即使它们具有相同的名称,它们也不被认为是相同的类型.这是因为我正在使用它Assembly.Load(byte[]).

问题

我怎么能绕过这个?我怎么能够,

  1. 加载程序集而不是锁定文件,和
  2. 提供正确的绑定上下文,以便我可以转换位于已加载程序集中的对象.

对不起文本墙,只是想获得所有相关信息.

.net c# plugins assemblies assembly-loading

7
推荐指数
1
解决办法
5652
查看次数

在仍使用依赖注入的同时创建新实例

快速描述环境:

我有一个代表聊天室的类,并且依赖于记录器.它与具有横切关注点的系统级记录器不同,而是与特定聊天室相关联的记录器.它将该聊天室中的所有活动记录到其唯一的日志文件中.创建聊天室时,我想打开日志文件,当它被销毁时,我想关闭日志文件.

问题

这是我正在使用的相关代码.

public interface IChatroomLogger
{
    void Log(ServerPacket packet);
    void Open();
    void Close();
}

public class ChatroomLogger : IChatroomLogger
{
    // chatroom name will be used as a file name
    public ChatroomLogger(string chatroomName) { ... }
    public void Log(ServerPacket packet) { ... }
}

public class Chatroom
{
    public Chatroom(string name, IChatroomLogger logger)
    {
        this.name = name;
        this.logger = logger;
        this.logger.Open();
    }

    public IChatromLogger Logger { get { return this.logger; } }
}

public interface IChatManager
{
    Chatroom …
Run Code Online (Sandbox Code Playgroud)

c# dependency-injection ioc-container unity-container

6
推荐指数
1
解决办法
3237
查看次数

自动混合和自定义数据注释

我在我的单元和集成测试中使用AutoFixture并遇到了问题.我正在生成数据传输对象,其中一些类在属性上具有DataAnnotation属性(其中一些是自定义的).AutoFixture可以看到这些并且不会为它们生成数据,可能是因为它不确定它所期望的数据.

我正在使用的自定义验证属性的示例:

public class Person 
{
   public string FullName { get; set; }

   [Enum("M", "F")]
   public string Gender { get; set; }
}

public class EnumAttribute : ValidationAttribute
{
   public EnumAttribute(params string[] allowedStrings)
    {
        if (allowedStrings == null || allowedStrings.Length == 0)
            throw new ArgumentException("allowedStrings");
        AllowNull = true;
        AllowedStrings = allowedStrings;
        ErrorMessage = "The field '{0}' is invalid. Allowed strings are " + string.Join(", ", AllowedStrings);
    }

    // ... implementation
}
Run Code Online (Sandbox Code Playgroud)

它只是将提供的字符串限制为某个值(由于其他原因,我无法使用直接枚举).

如何自定义Autofixture以创建适当的数据?

autofixture

6
推荐指数
1
解决办法
1153
查看次数

我应该如何在我的应用程序中构建日志?

所以我对此做了很多研究,并没有找到任何答案,我说,"是的,那就是".我希望那些博学多才的StackOverflow人群可以帮助我.

我在几个不同的场景中遇到过这个问题.假设我有一个C#应用程序,并且我想记录重要的事情.

public class MyClass
{
    ... 

    public void ImportantMethod()
    {
        DoInterestingThing();

        var result = SomethingElseImportant();
        if (result == null)
        {
            logger.Log("I wasn't expecting that. No biggie.");
            return;
        }

        MoreInterestingStuff(); 
}
Run Code Online (Sandbox Code Playgroud)

我感兴趣的事情是我在哪里得到logger.

我看到它有几个选择.

  1. 将它注入到构造函数中的MyClass中.
  2. 使用全局可用的服务定位器检索它.
  3. 使用方法装饰器和AOP为我完成日志记录.

这些似乎都不是很好的选择.#3看起来是不可能的,因为我正在我的业务逻辑中间进行记录而不只是简单地跟踪我的方法调用,输入参数和/或引发的异常.#2,虽然简单似乎很难进行单元测试.当然,我想要对所有内容进行单元测试.#1,虽然它可以正常工作,但是使用与业务对象本身无关的日志记录对象会使我的所有业务逻辑变得混乱.

关于上述选项之一的任何其他想法或想法?非常感谢!

编辑:只是要清楚,我已经知道如何做DI(我使用Unity),我已经知道一个很好的日志框架(我使用log4net).只是想知道如何以最智能的方式在应用程序中使用体系结构意义上的日志记录.


*编辑*

我将Mark Seeman的答案标记为解决方案.我浏览了我的应用程序,发现我的大多数日志记录调用都是装饰者可以做的事情.即,记录方法的条目,抛出任何异常,并退出返回值.

在某些情况下,我仍然需要直接在方法内部进行记录.一个例子是我希望在一个方法中快速失败的方法,该方法不返回任何东西但不抛出异常.在这些情况下,我有一个包含引用的单例,LogProvider它将依次检索一个命名的日志实例.代码看起来类似于:

private ILog logger = LogProviderFactory.Instance.GetLogger(typeof(Foo));
Run Code Online (Sandbox Code Playgroud)

LogProviderFactory有一个SetProvider允许你换出单例的方法.所以在单元测试中,我可以这样做:

// LogProviderFactory.Instance now is our mock
LogProviderFactory.SetProvider(MockLogProvider);
Run Code Online (Sandbox Code Playgroud)

日志记录装饰器使用与单例(它通过注入获得)相同的LogProvider,因此日志记录在整个系统中统一.

所以最终的解决方案主要是选项#3和混合#2(其中它是服务定位器模式,但服务被'注入'到定位器中).

AOP

就"面向方面的编程"而言,我对语言的局限性感到有些失望.希望AOP在未来版本中被视为一等公民.

  • 我试过PostSharp但是无法正确地在我的机器上运行它.此外,您必须在系统上安装PostSharp才能使用它(而不是仅仅调用解决方案附带的dll或类似的东西),这是一个很大的限制.
  • 我使用LinFu并且能够使其部分工作.然而,它在少数情况下爆炸了.新的2.0版本几乎没有记录,因此这是一个障碍.
  • 然而,与Unity的接口拦截似乎开箱即用.我很幸运,我想记录的大部分内容都是在实现接口的类中.

architecture logging dependency-injection cross-cutting-concerns service-locator

5
推荐指数
1
解决办法
2600
查看次数

通用Web API控制器

我正在使用Web API v2,我有一些模型,我需要做CRUD操作.例如,我有一个Allergy模型和一个Prescription模型.在应用程序本身中,我有可以转换为适当模型的视图模型,但为了简单起见,我只想说我在Web API控制器中直接使用模型.

所以像这样:

  public class PrescriptionsController
  {
        public HttpResponseMessage Put(Prescription model)
        {
              // saved to the DB
        }

        ... (other CRUD operations)
  }
Run Code Online (Sandbox Code Playgroud)

我对Allergy模型也有同样的看法:

  public class AllergiesController
  {
        public HttpResponseMessage Put(Allergy model)
        {
              // saved to the DB
        }

        ... (other CRUD operations)
  }
Run Code Online (Sandbox Code Playgroud)

两种型号都具有不同的属性,但处理方式完全相同 - 实际上我有大约3种其他型号,每种型号的处理方式完全相同.我讨厌有5个不同的端点,基本上是复制和粘贴代码.

所以我的问题是:

我可以制作一个通用控制器来处理所有这些模型吗?有点像MyCommonController<T>?(但当然有更好的名称!)Web API可以处理该场景中的路由吗?这是一个好主意吗?

c# generics asp.net-web-api

5
推荐指数
1
解决办法
7369
查看次数